質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

エスケープ処理

エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

Q&A

解決済

2回答

2689閲覧

正規表現を用いたエスケープについて

litteone

総合スコア10

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

エスケープ処理

エスケープ処理とは、一連の文字や一文字に対して、一定の規則に従って別の意味を適用する処理過程です。

正規表現

正規表現とは特定の文字列によるパターンマッチングを行う際に用いられる宣言型プログラミングです。

0グッド

0クリップ

投稿2017/04/18 05:44

編集2017/04/18 09:57

正規表現を用いたエスケープについて

テスト1{=test1-string1.test2-string2}-終わり
上記のような文字列があった場合に
中括弧内の-にのみマッチするような正規表現を考えております。
現在以下の通りに正規表現を組んでおりますが、

([^}]*\{=[^.}]*\.[^}]*)(-)([^}]*\})

.以降のみの-にのみマッチしてしまいます。
テスト1{=test1-string1.test2-string2}-終わり

やりたいことは以下の通りです。
テスト1{=test1-string1.test2-string2}-終わり

実装はこちらです。

java

1String regex = "([^}]*\\{=[^.}]*\\.[^}]*)(-)([^}]*\\})"; 2Pattern p = Pattern.compile(regex); 3Matcher m = p.matcher(string); 4while(m.find()) { 5 string = m.replaceAll("$1\\\\-$3"); 6}

{}内の-にマッチするような正規表現がわかる方がいらしましたら、
ご教示いただけないでしょうか。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2017/04/18 07:26

大括弧というのは [] のことですが、中括弧ではないでしょうか? また、- にマッチするということは、最終的にほしいのは - があるかないかということですか? その前後の文字はいらないのですか?
litteone

2017/04/18 07:29

失礼いたしました。中括弧でございます。エスケープ処理を加えたいので、最終的にやりたいことは、中括弧内に-があれば\-に置換することです。
Zuishin

2017/04/18 07:30

了解しました。ありがとうございます。
guest

回答2

0

ベストアンサー

二段階になりますが、こんな感じでどうでしょうか?

Java

1import java.util.*; 2import java.util.regex.*; 3import java.lang.*; 4import java.io.*; 5 6class Ideone 7{ 8 public static void main (String[] args) throws java.lang.Exception 9 { 10 System.out.println(replaceHyphenInBrace("テスト1{=test1-string1.test2-string2}-終わり")); 11 } 12 13 public static String replaceHyphenInBrace(String input) 14 { 15 Pattern p = Pattern.compile("\\{[^}]*}"); 16 StringBuffer buffer = new StringBuffer(); 17 Matcher m = p.matcher(input); 18 while (m.find()) 19 { 20 m.appendReplacement(buffer, m.group().replaceAll("-", "\\\\\\\\-")); 21 } 22 m.appendTail(buffer); 23 return buffer.toString(); 24 } 25}

投稿2017/04/18 08:45

Zuishin

総合スコア28660

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

litteone

2017/04/18 09:18

なぜかDEBUGするとm.find()がfalseになりエスケープ処理が走らないですが、通常通り実行すると問題なく動作しました。ありがとうございます。 ちなみに{}内に含まれている/も同様にescape処理を加えたい場合はwhile句内に同様に置換処理をいれればよいでしょうか。
Zuishin

2017/04/18 09:22

.replaceAll("[-\\\\]", "\\\\\\\\$0") と書き換えたらできると思います。
litteone

2017/04/18 09:54

.replaceAll("[-\\\\]", "\\\\\\\\$0") だと{}外にある/を-に変換してしまい、期待結果取れなかったです、、、
Zuishin

2017/04/18 10:06

括弧外は置換対象ではないのでそんなはずはないんですがねえ。再現しません。
litteone

2017/04/18 10:23

そうですよね。 m.appendReplacement(buffer, m.group().replaceAll("-", "\\\\\\\\-")); m.appendReplacement(buffer, m.group().replaceAll("/", "\\\\\\\\/")); のように連続でリプレイスかけるような事はできないでしょうか。 エラーで落ちちゃうので、同じ期待結果が取れれば問題ないのですが、まだ理解が及んでおりません。
Zuishin

2017/04/18 11:00 編集

appendReplacement は正規表現に前回マッチした部分以降で今回マッチした部分以前の部分と、置換文字列を StringBuffer に追加しています。詳しくは調べてください。 ですから、これを二回呼び出すと、同じものが二回追加されます。 m.group() が中括弧の中の文字列で、replaceAll() で - を \- に置換しています。 中括弧の中の文字列をこのハイフン置換後の文字列で置換しています。 つまり、いじるべきはこの部分です。 意味もわからず適当にいじるのではなく、遠回りしているように見えても、どんな処理をしているかをまず理解してから変更することをお勧めします。 とりあえずここで理解すべきは Matcher オブジェクトと StringBuffer です。これを使いこなせるようになってから改造してください。 追加の問題に取り掛かっているようですが、意味もわからずコピペは恥ずべき行いです。しっかりリファレンスとにらめっこして消化し、自分のものにしてから次に進むことをおすすめします。
litteone

2017/04/19 01:16

ご指導いただきありがとうございます。仰るとおりだと思います。 理解をする前に先に結果を求めてしまいました。 自分のものにできるように、Matcher、StringBufferについて深堀りします。 その上で追加の課題にあたろうと思います。
guest

0

JavaScript

1'use strict'; 2function sample (string) { 3 var brackets = string.match(/{[^{}-]*(?:-[^{}-]*)+}/g); 4 5 if (brackets) { 6 for (var i = 0, len = brackets.length; i < len; ++i) { 7 brackets[i] = brackets[i].slice(1, -1).match(/-|[^-]+/g); 8 } 9 } 10 11 return brackets; 12} 13 14console.log(JSON.stringify(sample('テスト1{=test1-string1.test2-string2}-終わり'))); // [["=test1","-","string1.test2","-","string2"]] 15console.log(JSON.stringify(sample('-{test1-string1}-{test2}-{test3-foo3-piyo3}'))); // [["test1","-","string1"],["test3","-","foo3","-","piyo3"]]

Re: litteone さん

投稿2017/04/18 06:14

編集2017/04/18 06:39
think49

総合スコア18162

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

litteone

2017/04/18 07:08

回答ありがとうございます。 現在javaScriptではなくJavaで実装しており、 ご回答いただいた正規表現の部分がIDE上でエラーで怒られてしまいました。
think49

2017/04/18 07:59

正規表現は一度消費した文字列に二度マッチさせることは出来ません。 {} 内の - は "{" を消費しないと判定できない為、{} にマッチさせた後に "-" をマッチさせてください。 Javaは知らないのでコードを書けませんが、原理上はこれで上手くいくと思います。
litteone

2017/04/18 08:05

承知いたしました。分割して試してみます。
think49

2017/04/18 09:01

JavaScript では String.prototype.replace でコールバック関数を指定できるので一度のマッチで置換処理も行えますが、Java にも同様の関数があるといいですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問