使用正则表达式从文本获取对话片段

时间:2010-06-01 05:46:42

标签: java regex

我正在尝试从书籍文本中提取对话片段。例如,如果我有字符串

"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对双引号有\"的事实?

1 个答案:

答案 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!

如前所述,这种复杂的模式对于自然语言文本不是必需的,它不太可能包含转义引号。

另见