我有以下代码,正则表达式是指定的输入,导致下面的输出结果如下。但是,unicode字符导致m.find()抛出异常。如果在文本中“Unicode”之前删除unicode char,一切正常。
所以,我尝试装饰我的正则表达式以使用\ Q \ E来逃避/计算任何unicode字符(不确定这是否是正确的方法或者我是否正确执行)。但是,它会阻止异常,但现在它与m.find()不匹配。
如何正确地转义此unicode(以及任何unicode char)?
String text = "Hi\n\nyo keep this here\n\nUnicode b4 keep all from here\n\nyo\ncut me:\n\nThis should be deleted";
Pattern PATTERN = Pattern.compile("^\\Q(.+?)\\nyo(?:(?!cut me:|\\nyo).)*cut me:\\E",
Pattern.DOTALL);
Matcher m = PATTERN.matcher(text);
if (m.find()) {
text = m.group(1);
System.out.println(text);
}
输出:
您好
哟保持这里
Unicode b4将所有内容保留在此处
答案 0 :(得分:3)
使用\Q
和\E
实际上会改变正则表达式的行为:正如您所写的那样,它将与该序列完全匹配:
(.+?)\\nyo(?:(?!cut me:|\\nyo).)*cut me:
也就是说,它通常会尝试找到parenthesis
,然后是文字dot
,后跟文字+
,依此类推......
澄清一点:
final Pattern PATTERN = Pattern.compile("^\\Q(.+?)\\nyo(?:(?!cut me:|\\nyo).)*cut me:\\E", Pattern.DOTALL);
final Matcher m = PATTERN.matcher("(.+?)\\nyo(?:(?!cut me:|\\nyo).)*cut me:");
System.out.println(m.match()); // true
答案 1 :(得分:2)
正如另一个答案所说,\Q
和\E
会导致正则表达式中的所有字符都被解释为与自己匹配的引用字符。
答案是升级到Java 8.该错误似乎已修复。
这是一个用全ASCII字符编写的程序,它复制了行为:
import java.util.regex.*;
class Test {
public static void main(String[] args) {
char[] special = Character.toChars(0x1F4F1);
String text = "Hi\n\nyo keep this here\n\n" + new String(special) + "Unicode b4 keep all from here\n\nyo\ncut me:\n\nThis should be deleted";
Pattern PATTERN = Pattern.compile("^(.+?)\\nyo(?:(?!cut me:|\\nyo).)*cut me:",
Pattern.DOTALL);
Matcher m = PATTERN.matcher(text);
if (m.find()) {
text = m.group(1);
System.out.println(text);
}
}
}
使用Java 7编译并运行它会导致:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.charAt(String.java:695)
at java.util.regex.Pattern$Slice.match(Pattern.java:3867)
at java.util.regex.Pattern$GroupCurly.match0(Pattern.java:4360)
at java.util.regex.Pattern$GroupCurly.match0(Pattern.java:4354)
at java.util.regex.Pattern$GroupCurly.match(Pattern.java:4304)
at java.util.regex.Pattern$Slice.match(Pattern.java:3870)
at java.util.regex.Pattern$GroupTail.match(Pattern.java:4615)
at java.util.regex.Pattern$Curly.match1(Pattern.java:4185)
at java.util.regex.Pattern$Curly.match(Pattern.java:4134)
at java.util.regex.Pattern$GroupHead.match(Pattern.java:4556)
at java.util.regex.Pattern$Begin.match(Pattern.java:3472)
at java.util.regex.Matcher.search(Matcher.java:1199)
at java.util.regex.Matcher.find(Matcher.java:592)
at Test.main(Test.java:9)
使用Java 8:
Hi
yo keep this here
?Unicode b4 keep all from here
(我的系统无法正确输出特殊字符。)