Regex 如何找到2个或更多连续的大写单词,而剩余的单词是非大写单词

Regex 如何找到2个或更多连续的大写单词,而剩余的单词是非大写单词,regex,text,information-retrieval,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

我正在尝试使用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)
这将有助于获得匹配项的开始偏移量和结束偏移量

为简单起见,假设只存在一个匹配项。 i、 e不会有这样的输入

 5. Abc Abcabc 123,00 test ABCDTEST XYZTEST XY  agab WXYZ ABCDE
但是,如果你也能解决这个问题的话,那就要额外加分

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

将匹配2个或更多大写字母

所以,它可以处理你的案例1-3,但不是4


我还不知道该怎么做,但我会再考虑一下这对你有用吗

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

如果一行中没有两个匹配的图案:

^(?=.*[a-z]).*?(\b[A-Z]+(?:\h+[A-Z]+\b)+)
将结果存储在第一个捕获的组中。如果你的字符串是多行的,你要逐行地考虑它,使用<代码> g <代码>(不要停止在第一次匹配)和<代码> M< /代码>(多行)标志。< /P> 演示:

解释

  • ^(?=.[a-z])
    :从行首检查是否至少有一个小写字母
  • (\b[A-Z]+(?:\h+[A-Z]+\b)+)
    • \b[A-Z]+
      :检查是否存在全大写单词
    • \h+[A-Z]+\b
      :…至少由一个空格隔开(
      \h
      是水平空格的缩写,即空格、制表符…但没有换行符)与另一个全大写单词
    • (?:\h+[A-Z]+\b)+
      :…后面可能跟有其他所有大写单词(
      (?:)
      是非捕获组)
警告

\b
将允许像
abc ABD
这样的内容。如果存在发生这种情况的风险,可以使用以下内容替换正则表达式:

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


这一点也不漂亮,也不能解决“一行两对”的问题。请随意评论

这可能有效,但如果你只是在学习,可能需要掌握很多。
正则表达式:


(?!^[^\S\n]*(?:[A-Z]+[^\S\n]*)*$)^.*(?:^^[A-Z]+)谢谢。我试图测试你的解决方案。请单击此链接,不确定为什么没有匹配你可能输入错误并忘记了加号:
(?:\S+[A-Z]+)在ReGEX的中间。这是为了找到两个或多个大写的词,但实际上不检查小写的东西……也要小心,因为它将匹配<代码> 123-ABC DEF 456 对不起,你到底想要匹配什么?一个至少有1个小写字母的字符串,你想得到字母串吗?如果所有的例子都不清楚,请用大写字母表示歉意。我正在尝试按顺序匹配所有大写字母的单词,例如:“ABC”不管前面是否有1个小写。@Watt:多重匹配的事情让我抓狂:这里有更多关于这个主题的信息。如果小写部分不直接在大写部分之前,它就不起作用。它也不检查是否有两个连续的大写字:/it检查2个大写。它在
abB ABD ABD上中断
和on
ab ABC a
(在
ABC
a
之间有两个空格,由SO注释标记删除):/+1感谢您的详细解释。您的正则表达式可能需要稍微调整。出于某种原因,它与示例3的第一个单词匹配,而在该示例中,第四个和第五个单词应该匹配。请参见此处,但我看到您的演示显示它正确匹配。因此,可能与rubular有关,而不是与您的解决方案有关。忽略我之前的评论。我会尝试我的java代码,一旦我成功了,我会接受答案。今天我学到了很多关于RegExp的新东西。我相信Rubular不知道单词边界
\b
,并且把它当作一个普通的转义
b
。。。
^(?=.*[a-z]).*?(\b[A-Z]+(?:\h+[A-Z]+\b)+)
^(?=.*[a-z]).*?((?:^|\h+)[A-Z]+(?:\h+[A-Z]+(?=\h+|$))+)
 (?!^[^\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