我正在尝试从一本书的文本中提取对话片段。例如,如果我有一个字符串
"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,它是"[^"\\]*(\\.[^"\\]*)*"
。当我在我的书.txt文件上执行Ctrl+F find regex时,这在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 String对双引号有一个\"
这一事实?
发布于 2010-06-01 13:49:21
在自然语言文本中,"
不太可能通过前面的斜杠进行转义,因此您应该只能使用模式"([^"]*)"
。
作为一个Java string文本,它是"\"([^\"]*)\""
。
这是用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!
如前所述:这种复杂的模式对于自然语言文本来说不是必需的,因为自然语言文本不太可能包含转义引号。
另请参阅
https://stackoverflow.com/questions/2947502
复制相似问题