[英]Unescaped java not matching in regex matcher.find()
我有以下基本上與“匹配此:”匹配的代碼,並保留第一句話。 但是,有時會有Unicode字符傳遞到文本中,從而導致在其他更復雜的正則表達式上回溯。 轉義似乎減輕了超出范圍例外的回溯索引。 但是,現在正則表達式不匹配。
我想知道的是,為什么此正則表達式在轉義時不匹配? 如果您注釋掉了轉義/ unescape java行,則所有內容都會被刪除。
String text = "Keep this\n\n"
+ "Match this:\n\nDelete 📱 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);
我想知道的是,為什么此正則表達式在轉義時不匹配?
當您轉義類似於"foo\\nbar"
字符串時,其輸出類似於
foo
bar
你會得到"foo\\\\nbar"
,它看起來像
foo\nbar
發生這種情況是因為StringEscapeUtils.escapeJava
也轉義了\\n
並將其替換為\\\\n
,所以它不再是行分隔符而是簡單的文字,因此無法與^
或$
匹配。
可能的解決方案是在StringEscapeUtils.escapeJava
之后用"\\n"
代替"\\\\n"
。 您將需要在這里小心,不要“ unscapee”真實的"\\\\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
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.