java中的正则表达式不会产生所需的结果

时间:2012-02-21 17:30:28

标签: java regex pattern-matching

我需要从包含大量随机数据的文本字符串中提取关键字。在Regular expression not extracting the exact pattern分享,我创建了一个正则表达式:

Pattern p = Pattern.compile("\\b"+myKeywordToSearch+"s?\\b",Pattern.CASE_INSENSITIVE);

然而,在关键字开始之前,这忽略了具有数字/特殊字符的任何关键字。

如上所述,我需要将所有这些关键字统计为:

12312312face
1face
$face
234%#$face
faces
4faces
$faces
 faces
 face's
 faces'

虽然我不接受像:

这样的关键词
facebook
duckface

我写过正则表达式

        Pattern p = Pattern.compile("\\b\\W"+myKeywordToSearch+"s?\\b",Pattern.CASE_INSENSITIVE);

其中keyword是我的关键字列表,但我没有得到理想的结果。关键字的数量非常低,并不像我预期的那么多。你能阅读我的描述吗,请说明可能存在的问题以及我如何解决它?

我的正则表达式要求是在文件中搜索关键字:

5face 
7face
$face
%face
 face
faces
face's
faces'
face'
face4
face$
face    <--Space after face

但不得阅读

duckface
duckface1
duckface$
facebook
 facebook
3facebook
&facebook 
and so on...

到目前为止,我的正则表达式尝试效果不佳..

任何人都可以提出建议。谢谢。

我多次尝试

("\\b"+mySearchKeyWord+"s?\\b",Pattern.CASE_INSENSITIVE);
            ("\\b\\W"+mySearchKeyWord+"s?\\b",Pattern.CASE_INSENSITIVE);
            ("[0-9]{}//w[a-bA-B]+ or [0-9]{}//w["+mySearchKeyWord+"]++",Pattern.CASE_INSENSITIVE);
            ("[^a-z\\s]*"+mySearchKeyWord+"?[^\\s]*",Pattern.CASE_INSENSITIVE);
            ("[^\\s]*"+mySearchKeyWord+"?[^\\s]",Pattern.CASE_INSENSITIVE);
            ("[^\\s]*"+mySearchKeyWord+"s?\\b",Pattern.CASE_INSENSITIVE);
            ("[^\\s]*\\W*"+mySearchKeyWord+"s?\\b",Pattern.CASE_INSENSITIVE);

6 个答案:

答案 0 :(得分:1)

\ b是一个单词边界,数字包含在可形成单词的内容中,因此“1face”被认为是正则表达式中的单词,这意味着\ bface \ b将不匹配它。我不确定哪些特殊字符被认为是Java中单词的一部分,所以这也可能是以单词开头的单词的问题。

答案 1 :(得分:1)

您的模式看起来没问题,因此要了解问题所在,您必须发现输入并找到模式未捕获的特定单词。

但我可以向你推荐一些东西吗?如果您的文本相对较短且关键字数量相对较少,则应创建一个模式,其中包含由|分隔的所有关键字,然后仅运行一次模式。

据我所知,你现在在整个文本上运行你的模式N次,其中N是关键字的数量。这是非常无效的。

但是,如果您有很多关键字(数千个左右),则应将文本拆分为单独的字词,并使用Map等数据结构来定位关键字。太长的图案不能很好地工作。

答案 2 :(得分:1)

我并不声称自己是正则表达专家,但这似乎可以捕捉到您示例中的所有字词:

[^a-z\s]*faces?[^\s]*

这基本上可以找到“面子”或“面孔”以及它之前和之后的一切,直到它找到一个空间。将整个表达式括在括号中会将所有单词都放在捕获组中。

答案 3 :(得分:0)

您可以使用前瞻和后视而不是单词边界:

"(^|(?<=[^a-zA-Z]))(faces?)($|(?=[^a-zA-Z]))"

这断言我必须能够在“face / faces”之前和之后看到非字母字符(或字符串的开头/结尾)。

答案 4 :(得分:0)

这没有任何意义:为什么要搜索边界,然后是非字符字符,然后是任意字符串?看起来你不明白界限是什么。

\b边界恰好等同于:

(?:(?<=\w)(?!\w)|(?<!\w)(?=\w))

看到你的问题?当你写\b\Wface时,你需要一个wordchar,然后是一个nonwordchar,然后是face

如果您不理解边界,请不要使用边界。

答案 5 :(得分:-1)

所以关键字只是字符连续,所以看起来你可能不想使用模式匹配器,而是尝试使用java.regex.pattern。

为正则表达式注入类似的东西:

 [0-9]{*}//w[a-bA-B]+ or [0-9]{*}//w[face]++ 

这是一个测试人员RegExp