タグ内のみに置き換える正規表現を記述する必要がありa
ます。b
<pre>
例
a <pre> c a <foo> a d </pre> a
結果
a <pre> c b <foo> b d </pre> a
JavaString.replace
関数の式を書くのを手伝ってください。pre
タグがネストされていないという保証があります。
String.replace() でできる最善のことは次のようなものだと思います:
String string = ...
for (;;)
{
String original = string;
string = string.replaceFirst("(<pre>.*?)a(.*?</pre>)", "$1b$2");
if (original.equals(string))
break;
}
( EDIT : @Bohemian は、上記の正規表現が正しく機能しないことを指摘しました。そのため、
(<pre>(?:(?!</pre>).)*a((?:(?!<pre>).)*</pre>)
(未テスト) に変更して、セクション外での一致を回避する必要があります。この変更により、量指定子<pre>...</pre>
は必要なくなり、より多くの*?
一般的な「貪欲な」 ( *
) 量指定子. これは私の他の答えによく似ているように見え始めています.
あなたはMatcherを使ったほうがいいです(頭のてっぺんからコードをたどります):
import java.util.regex.Pattern;
import java.util.regex.Matcher;
Pattern pattern = Pattern.compile("(?<=<pre>)(.*?)(?=</pre>)");
Matcher m = pattern.matcher(string);
StringBuffer replacement = new StringBuffer();
while (matcher.find())
{
matcher.appendReplacement(replacement, "");
// Careful using unknown text in appendReplacement as any "$n" will cause problems
replacement.append(matcher.group(1).replace("a", "b"));
}
matcher.appendTail(replacement);
String result = replacement.toString();
編集<pre>
:上記のパターンを変更して、周囲の と に一致しないようにし</pre>
ました。
これが仕事をする正規表現です(私は思う:すべてのテストに合格することにあまり賭けないでしょう)
String replacement = original.replaceAll(
"(?<=<pre>(?:(?!</pre>).){0,50})a(?=(?:(?!<pre>).)*</pre>)",
"b");
説明:
(?<=<pre>(?:(?!</pre>).){0,50})
<pre>
- 前にトラバースしない限り、先行
するものを後読み</pre>
します。Java では有限の最大長の後読みが必要なため、{0,50}
ではなくを使用します*
。a
- 置き換えたいキャラクター(?=(?:.(?!<pre>))*</pre>)
-</pre>
過去をたどらない限り、先を見据えてください<pre>
。Pattern pattern = Pattern.compile("<pre>(.+?)</pre>");
java.util.regex.Matcher matcher = pattern.matcher("a <pre> c a <tag> a d </pre> a");
これを試して: