1

你能帮我找到一个包含短语列表的正则表达式,并检查给定文本中是否存在这些短语之一,好吗?

例子:

如果我有hashSet以下的话:

كيف الحال  
إلى أين  
أين يوجد  
هل من أحد هنا  

给定的文本是:كيف الحال أتمنى أن تكون بخير

我想在执行正则表达式后得到:كيف الحال

我的初始代码:

HashSet<String> QWWords = new HashSet<String>();

QWWords.add("كيف الحال");
QWWords.add("إلى أين");
QWWords.add("أين يوجد");
QWWords.add("هل من أحد هنا");

String s1 = "كيف الحال أتمنى أن تكون بخير";

for (String qp : QWWords) {

    Pattern p = Pattern.compile("[\\s" + qp + "\\s]");

    Matcher m = p.matcher(s1);

    String found = "";

    while (m.find()) {
        found = m.group();
        System.out.println(found);

    }

}
4

1 回答 1

4

[...]字符类,字符类只能匹配它指定的一个字符。例如字符类 like[abc]只能匹配aOR bOR c。因此,如果您只想找到单词abc,请不要用[...].

另一个问题是您使用\\s的是单词分隔符,因此在以下字符串中

String data = "foo foo foo foo";

正则表达式\\sfoo\\s将无法首先匹配foo,因为之前没有空格
所以它会找到的第一个匹配将是

String data = "foo foo foo foo";
//      this one--^^^^^

现在,由于正则表达式在第二个之后消耗了空间,foo它不能在下一场比赛中重用它,所以第三个foo也将被跳过,因为在它之前没有可匹配的空间。
你也不会匹配,因为这一次后面foo没有空间。

要解决此问题,您可以使用\\b- word boundary检查它所代表的位置是否在字母数字和非字母数字字符(或字符串的开头/结尾)之间。

所以而不是

Pattern p = Pattern.compile("[\\s" + qp + "\\s]");

利用

Pattern p = Pattern.compile("\\b" + qp + "\\b");

或者像蒂姆提到的那样更好

Pattern p = Pattern.compile("\\b" + qp + "\\b",Pattern.UNICODE_CHARACTER_CLASS);

确保\\b在预定义的字母数字类中包含阿拉伯字符。

更新:

我不确定您的单词是否可以包含正则表达式元字符等{ [ + *,因此以防万一您还可以添加转义机制以将此类字符更改为文字。

所以

"\\b" + qp + "\\b"

可以变成

"\\b" + Pattern.quote(qp) + "\\b"
于 2014-05-17T12:02:45.860 回答