我正在尝试从书籍文本中提取对话片段。例如,如果我有字符串
"What's the matter with the flag?" inquired Captain MacWhirr. "Seems all right to me."
然后我要提取"What's the matter with the flag?"
和"Seem's all right to me."
。
我找到了一个使用here的正则表达式,即"[^"\\]*(\\.[^"\\]*)*"
。当我在我的book .txt文件中执行Ctrl + F查找正则表达式时,这在Eclipse中很有用,但是当我运行以下代码时:
String regex = "\"[^\"\\\\]*(\\\\.[^\"\\\\]*)*\"";
String bookText = "\"What's the matter with the flag?\" inquired Captain MacWhirr. \"Seems all right to me.\""; Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(bookText);
if(m.find())
System.out.println(m.group(1));
唯一打印的是null
。那我不是正确地将正则表达式转换为Java字符串吗?我是否需要考虑Java Strings对双引号有\"
的事实?
答案 0 :(得分:5)
在自然语言文本中,"
不太可能被前面的斜杠转义,因此您应该只能使用模式"([^"]*)"
。
作为Java字符串文字,这是"\"([^\"]*)\""
。
这是Java:
String regex = "\"([^\"]*)\"";
String bookText = "\"What's the matter with the flag?\" inquired Captain MacWhirr. \"Seems all right to me.\"";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(bookText);
while (m.find()) {
System.out.println(m.group(1));
}
以上版画:
What's the matter with the flag?
Seems all right to me.
鉴于此声明:
String s = "\"";
System.out.println(s.length()); // prints "1"
字符串s
只有一个字符"
。 \
是Java源代码级别的转义序列;字符串本身没有斜线。
模式本身并没有什么问题,但你没有捕捉到正确的部分。 \1
未捕获引用的文字。这是具有正确捕获组的模式:
String regex = "\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\"";
String bookText = "\"What's the matter?\" inquired Captain MacWhirr. \"Seems all right to me.\"";
Pattern p = Pattern.compile(regex);
Matcher m = p.matcher(bookText);
while (m.find()) {
System.out.println(m.group(1));
}
对于视觉比较,这是原始模式,作为Java字符串文字:
String regex = "\"[^\"\\\\]*(\\\\.[^\"\\\\]*)*\""
^^^^^^^^^^^^^^^^^
why capture this part?
这是修改后的模式:
String regex = "\"([^\"\\\\]*(?:\\\\.[^\"\\\\]*)*)\""
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
we want to capture this part!
如前所述,这种复杂的模式对于自然语言文本不是必需的,它不太可能包含转义引号。