我有以下代码,基本上匹配"匹配这个:"并保留第一句话。 但是,有时会将 unicode 字符传递到文本中,从而导致其他更复杂的正则表达式的回溯。转义似乎可以缓解回溯指数超出范围的异常。 但是,现在正则表达式不匹配。
我想知道的是为什么这个正则表达式在转义时不匹配? 如果你注释掉 escape/unescape java 会排列所有内容。
String text = "Keep thisnn"
+ "Match this:nnDelete 📱 this";
text = org.apache.commons.lang.StringEscapeUtils.escapeJava(text);
Pattern PATTERN = Pattern.compile("^Match this:$",
Pattern.MULTILINE);
Matcher m = PATTERN.matcher(text);
if (m.find()) {
text = text.substring(0, m.start()).replaceAll("[\n]+$", "");
}
text = org.apache.commons.lang.StringEscapeUtils.unescapeJava(text);
System.out.println(text);
我想知道的是为什么这个正则表达式在转义时不匹配?
当您转义字符串时,打印的字符串类似于 "foonbar"
foo
bar
你得到"foo\nbar"
打印看起来像
foonbar
发生这种情况是因为StringEscapeUtils.escapeJava
转义也n
并用\n
替换它,所以它不再是行分隔符,而是简单的文字,所以它不能与^
或$
匹配。
可能的解决方案可能是在StringEscapeUtils.escapeJava
后用"n"
替换回"\n"
。您在这里需要小心,不要"逃脱"真正的"\n"
更换后会给您带来"\\n"
打印看起来像\n
.所以也许使用
text = org.apache.commons.lang3.StringEscapeUtils.escapeJava(text);
text = text.replaceAll("(?<!\\)\\n", "n");// escape `n`
// if it is not preceded with ``
//do your job
//and now you can unescape your text (n will stay n)
text = org.apache.commons.lang3.StringEscapeUtils.unescapeJava(text);
另一种选择可能是创建自己的实现,类似于 StringEscapeUtils.escapeJava
.如果你看一下这个方法体,你会看到
return ESCAPE_JAVA.translate(input);
ESCAPE_JAVA
在哪里
CharSequenceTranslator ESCAPE_JAVA =
new LookupTranslator(
new String[][] {
{""", "\""},
{"\", "\\"},
}).with(
new LookupTranslator(EntityArrays.JAVA_CTRL_CHARS_ESCAPE())
).with(
UnicodeEscaper.outsideOf(32, 0x7f)
);
和 EntityArrays.JAVA_CTRL_CHARS_ESCAPE()
返回克隆
String[][] JAVA_CTRL_CHARS_ESCAPE = {
{"b", "\b"},
{"n", "\n"},
{"t", "\t"},
{"f", "\f"},
{"r", "\r"}
};
数组。因此,如果您在此处提供自己的表,该表将明确告知n
应该保持原样(因此应该将其替换为自身n
),您的代码将忽略它。
所以这就是你自己的实现的样子
private static CharSequenceTranslator translatorIgnoringLineSeparators =
new LookupTranslator(
new String[][] {
{ """, "\"" },
{ "\", "\\" },
}).with(
new LookupTranslator(new String[][] {
{ "b", "\b" },
{ "n", "n" },//this will handle `n` and will not change it
{ "r", "r" },//this will handle `r` and will not change it
{ "t", "\t" },
{ "f", "\f" },
})).with(UnicodeEscaper.outsideOf(32, 0x7f));
public static String myJavaEscaper(CharSequence input) {
return translatorIgnoringLineSeparators.translate(input);
}
此方法将防止转义r
和n
。