9

Android で次のテキストが変更されないのはなぜですか?

String content = "test\n=test=\ntest";
content = content.replaceAll("^=(.+)=$", "<size:large>$1</size:large>")

元の値を変更せずに返します。私はそれが真ん中=test=<size:large>test</size:large>

ここで何が欠けていますか?

編集:わかりました、私は理由を理解していますが、うまく^いき$ません。ポイントは、行頭と行末の両方でテキストに一致する何かが必要だということです。たとえば、「=some text=」のみを含む行です。次の理由により、与えられた回答のほとんどは十分ではありません。

=(.+)=は行末とは何の関係もないため、並んで=いない 2 つの行と一致します。

.*=(.+)=.*行全体に一致しますが、前と同じ問題があります

\n=(.+)=\n近くなりますが、2 行連続には一致しません (例test\n=test=\n=test=\ntest) 最初または最後の行のインスタンスにも一致しません

(?<=\n)=(.+)=(?=\n)ほとんど機能しますが、最初または最後の行のインスタンスと一致しません

(?<!.)=(.+)=(?!.)=たとえば、 で始まり で終わるすべての行に実際に一致するように見える唯一のものですが、 $1 には置換文字列と元の文字列の両方が含まれています。

content = content.replaceAll("(?<=(\n|^))=(.+)=(?=(\n|$))", "<size:large>$2</size:large>");実際にすべきことをしているように見える唯一の答えです。

4

5 に答える 5

10

次を使用して複数行モードをオンにすると、元の正規表現は正常に機能します(?m)

content = content.replaceAll("(?m)^=(.+)=$", "<size:large>$1</size:large>");

Now^$do は実際に行の境界で一致します。

于 2012-08-24T00:37:30.490 に答える
4

これに対処する最良の方法は、を設定することPattern.MULTILINEです。MULTILINE^を使用すると、、$のみを使用して区切られた行に一致し\n、入力の開始と入力の終了を同様に処理します。

を使用すると、埋め込みフラグ式を使用してパターンString.replaceAllにこれらを設定する必要があります。(?m)MULTILINE

content = str.replaceAll("(?m)^=(.+)=$", "<size:large>$1</size:large>");

を使用しない場合は、ポジティブルックアヘッドとルックビハインドMULTILINEを使用する必要があります。最初の行と最後の行に一致するために正規表現が複雑になります。たとえば、入力が次の場合などです。\n\n=test=\n=test=\n=test=\n=test=

String pattern = "(?<=(^|\n))=(.+)=(?=(\n|$))";
content = str.replaceAll(pattern, "<size:large>$2</size:large>");

このパターンでは、後読みのオプションを提供しています。\n または入力の開始、(^|\n); 先読みの場合:\n または入力の終わり、(\n|$)最初のまたは$2によって導入されたグループのため、置換でキャプチャされたグループ参照として使用する必要があることに注意してください。

キャプチャしないグループの先読み/後読みに次のような選択肢を導入することで、パターンをより複雑にすることができます(?:)

String pattern = "(?<=(?:^|\n))=(.+)=(?=(?:\n|$))";
content = str.replaceAll(pattern, "<size:large>$1</size:large>");

$1これで、置換でキャプチャされたグループとしての使用に戻ります。

于 2012-08-22T17:01:21.780 に答える
3

Java String オブジェクト\nでは、行頭または行末とは見なされません。改行です。これを一致させるには、コードを次のように変更する必要があります

String content = "test\n=test=\ntest";
content = content.replaceAll("\n=(.+)=\n", "\n<size:large>$1</size:large>\n");

What ^and $match は、String オブジェクト自体の先頭と末尾です。

ファイルから読み取っている場合、改行は CRLF 文字である可能性があり、その場合も一致させたいと考えてい\rます。その場合、このような正規表現を使用する必要があります

content = content.replaceAll("[\n\r]=(.+)=[\n\r]", "\n<size:large>$1</size:large>\n");

同じ文字列内の複数の「行」で複数のインスタンスで動作するように一致させる必要がある場合は、最初に文字列を複数の行に分割する必要があります。

String content = "test\n=test=\n=test=\ntest";
String[] pieces = content.split("[\r\n]");
StringBuilder replaced = new StringBuilder();

for (int i=0; i<pieces.length; i++) {
    String piece = pieces[i].replaceAll("^=(.+)=$", "<size:large>$1</size:large>");
    replaced.append(piece);
    replaced.append('\n');
}
于 2012-08-22T16:36:53.267 に答える
0

さて、答えがあると思います...これはうまくいくようです:

content = content.replaceAll("(?<!.)=(.+)=(?!.)", "<size:large>$1</size:large>")

そうじゃない?

編集:上記は機能しません。何らかの理由で元のテキストをコピーし、置換テキストの後に配置します...最終的に機能したのは次のとおりです:

content = content.replaceAll("(?<=(\n|^))=(.+)=(?=(\n|$))", "<size:large>$2</size:large>");
于 2012-08-22T16:53:46.587 に答える
0

さて、すでに述べたように、それは正規表現の開始/終了マーカーの問題です。^は行の先頭ではなく文字列全体の先頭であり、同様に文字列$全体の末尾です。

式を変更してみてください:^.*=(.+)=.*$またはそれらのマーカーを除外します:=(.+)=

行の先頭に一致させるには、これを使用できます: (?:^|\n)=(.*)=. プレーン Java での私のテストでは、末尾の改行が認識されないように見えますが、Android では異なる可能性があります。

于 2012-08-22T16:33:40.433 に答える