如何找到2个或更多连续的单词,其余的单词是非上限

时间:2014-02-17 20:47:39

标签: regex text information-retrieval

我正在尝试使用RegExp解决此问题。我相信这可以用Java和许多其他语言轻松解决。但是,我想用这个例子来进一步了解RegExp

对于以下4个输入句子:

1. Abc Abcabc 123,00 test ABCDTEST XYZTEST XY 
2. aBC Abcabc 24DD test ABCDTEST XYZTEST XY test is test
3. ABC Abcabc test ABCDTEST XYZTEST
4. ABC ABCABC TEST ABCDTEST XYZTEST

我想要匹配的术语:

1. ABCDTEST XYZTEST XY 
2. ABCDTEST XYZTEST XY   
3. ABCDTEST XYZTEST      (only two in end satisfies condition)         
4.                       (no match, because all of them are in caps)

获取匹配术语的起始偏移量和结束偏移量会很有帮助。

为简单起见,我们假设只有一个匹配存在。 即没有像这样的输入

 5. Abc Abcabc 123,00 test ABCDTEST XYZTEST XY  agab WXYZ ABCDE

但是,如果你能解决这个问题,还需要额外的信用。

这是我的初始正则表达式的样子(这是错误的)

(([A-Z]+){2}){2}

4 个答案:

答案 0 :(得分:1)

如果一行中没有两个匹配的模式:

^(?=.*[a-z]).*?(\b[A-Z]+(?:\h+[A-Z]+\b)+)

会将结果存储在第一个捕获的组中。如果您的字符串是多行的,并且您想逐行考虑,请使用g(不要在第一次匹配时停止)和m(多行)标记。

演示:http://regex101.com/r/qC2wF9

<强>解释

  • ^(?=.*[a-z]):从行的开头检查至少有一个小写字母。
  • (\b[A-Z]+(?:\h+[A-Z]+\b)+)
    • \b[A-Z]+:检查是否有全文字...
    • \h+[A-Z]+\b:...至少有一个空格(\h是水平空格的缩写,即空格,制表符......但没有换行符)来自另一个全大写单词...
    • (?:\h+[A-Z]+\b)+:...可能后跟其他所有大写字词((?: )是非捕获组)

警告

\b会允许abc-ABD ABD之类的内容。如果存在发生这种情况的风险,您可以使用以下命令替换正则表达式:

^(?=.*[a-z]).*?((?:^|\h+)[A-Z]+(?:\h+[A-Z]+(?=\h+|$))+)

<强>改进

这绝不是漂亮的,也不解决“一线两场比赛”的问题。随意评论!

答案 1 :(得分:0)

\b([A-Z]+(?:\s+[A-Z])+)\b

将匹配2个或更多全部大写字数

因此,它会处理您的案例1-3,但不会处理4

我想不出怎么做(4)但是我会考虑更多

答案 2 :(得分:0)

这对你有用吗?

[a-z]+[^A-Z]*\s([A-Z]+\s[A-Z\s]+)

http://regex101.com/r/lR3nN5

答案 3 :(得分:0)

这可能有用,但如果你只是在学习,可能会有很多把握 正则表达式:

 (?!^[^\S\n]*(?:[A-Z]+[^\S\n]*)*$)^.*?(?:^|(?<=[^\S\n]))([A-Z]+(?:[^\S\n]+[A-Z]+){1,})(?=[^\S\n]|$)

说明:

 # Modifier: multi-line mode  '(?m)'
 (?!                           # Ensure this is not a line of all caps (via assertion)
      ^                             # Beginning of line
      [^\S\n]* 
      (?: [A-Z]+ [^\S\n]* )*
      $                             # End of line
 )
 ^                             # Begining of line. Ok, this is a good candidate, check it 
 .*?                           # Slowly, creep up on it
 (?:                           # Here, the candidate must be qualified (via assertion)
      ^                             # Either start of the line
   |                              # or
      (?<= [^\S\n] )                # A non-newline whitespace separatore before us
 )
 (                             # (1 start), Capture our candidate
      [A-Z]+                        # First of all caps
      (?: [^\S\n]+ [A-Z]+ ){1,}     # Second to more all caps
 )                             # (1 end)
 (?= [^\S\n] | $ )             # Found them, but have to qualify  (via assertion)
                               #  there is a valid separator after us,
                               #  either non-newline whitespace or End of line