【问题标题】:RegEx to find the word between last Upper Case word and another word正则表达式查找最后一个大写单词和另一个单词之间的单词
【发布时间】:2014-01-15 07:03:03
【问题描述】:

我的问题是在两个词之间找到一个词。在这两个词中,一个是全大写的词,可以是任何东西,另一个词是“是”。我尝试了一些正则表达式,但没有一个对我有帮助。这是我的例子:

字符串:

In THE house BIG BLACK cat is very good.

预期输出:

cat

使用正则表达式:

(?<=[A-Z]*\s)(.*?)(?=\sis)

上面的 RegEx 给了我BIG BLACK cat 作为输出,而我只需要cat。

【问题讨论】:

  • 虽然我的问题得到了答案。我只是想弄清楚以下场景的正则表达式:

标签: java regex regex-lookarounds


【解决方案1】:

一个解决方案是稍微简化你的正则表达式,

[A-Z]+\s(\w+)\sis

并仅使用匹配的组(即\1)。 See it in action here.

既然你想出了更复杂的东西,我假设你理解上述表达的所有部分,但对于以后可能会出现的人,这里有更多细节:

  • [A-Z]+ 将匹配一个或多个大写字符
  • \s 将匹配一个空格
  • (\w+) 将匹配一个或多个单词字符 ([a-zA-Z0-9_]) 并将匹配存储在第一个匹配组中
  • \s 将匹配一个空格
  • is 将匹配“是”

我的示例非常具体,可能会因不同的输入而分解。您的问题没有提供有关您期望的其他输入的许多详细信息,因此我不确定我的解决方案是否适用于所有情况。

【讨论】:

  • 但不幸的是,OP 询问了[...] whereas I just need cat.,如果你按原样使用它,这不是这个正则表达式给出的。但是一般的正则表达式非常好:)
  • @avalancha 我有点困惑。正则表达式提供'cat',OP说他需要'cat'。怎么回事?
  • 我尝试了正则表达式here,它突出显示了BIG BLACK CAT。所以我认为您需要分组才能获得 only 猫。希望我没有记错...
  • 赞成解释正则表达式。当人们解释而不是让人们鹦鹉学舌解决方案时,它总是有帮助的。当然,有些人仍然只会鹦鹉学舌,但至少解释让他们可以选择不这样做。
  • @lostriebo 感谢您的详细解释,但下面 rbernabe 和 stema 的解决方案给了我我所需要的。我必须在我的应用程序中使用前瞻。但是非常感谢您让事情变得如此清晰
【解决方案2】:

试试这个:

String TestInput = "In THE house BIG BLACK cat is very good.";
    Pattern p = Pattern
            .compile(
                    "(?<=\\b\\p{Lu}+\\s)  # lookbehind assertion to ensure a uppercase word before\n"
                            + "\\p{L}+    # matching at least one letter\n" 
                            + "(?=\\sis)  # lookahead assertion to ensure a whitespace is ahead\n"
                            , Pattern.COMMENTS);    Matcher m = p.matcher(TestInput);
if(m.find())
    System.out.println(m.group(0));

它只匹配“猫”。

\p{L} 是 Unicode property,表示任何语言的字母。

\p{Lu} 是 Unicode property,表示任何语言的大写字母。

【讨论】:

  • 在多读了几次这个问题之后,我真的认为这就是 OP 想要的。
  • 感谢您的解决方案。这甚至适用于 Unicode 字符。干杯!
  • @stema 虽然我的问题得到了答案。我只是想弄清楚以下场景的正则表达式:匹配字符串中最后一个大写单词和其他单词之间的所有单词。例如,在字符串“In THE house BIUG BLACK cat is very good”中,匹配 BLACK [因为这是最后一个大写单词] 和 very 之间的所有单词。所以我匹配的字符串将是“cat is”
【解决方案3】:

您希望查找取决于信息的多个部分的条件,然后仅检索该信息的特定部分。这在没有分组的正则表达式中是不可能的。在 Java 中你应该这样做:

public class Main {

    public static void main(String[] args) {
        Pattern pattern = Pattern.compile("[A-Z]+\\s(\\w+)\\sis");
        Matcher matcher = pattern.matcher("In THE house BIG BLACK cat is very good.");

        if (matcher.find())
           System.out.println(matcher.group(1));
        }
    }
}

group(1) 是用括号括起来的那个。在这种情况下w+。这就是你的话。 group() 的返回类型是String 所以你可以马上使用它

【讨论】:

  • 赞成展示 java 实现并解释 group(1)。我在这里学到了一些新东西。
  • 当然可以不分组查找依赖于信息的几个部分的条件,然后只检索该信息的特定部分。 OP已经不远了。
【解决方案4】:

以下部分有异常行为

(?<=[A-Z]*\s)(.*?)

由于某种原因,[A-Z]* 匹配一个空字符串。 (.*?) 匹配 BIG BLACK。稍作调整,我认为以下方法会起作用(但它仍然与一些误报相匹配):

(?<=[A-Z]+\s)(\w+)(?=\sis)

稍微好一点的正则表达式是:

(?<=\b[A-Z]+\s)(\w+)(?=\sis)

希望对你有帮助

【讨论】:

    【解决方案5】:
     String  m = "In THE house BIG BLACK cat is very good.";
           Pattern p = Pattern.compile("[A-Z]+\\s\\w+\\sis");
           Matcher m1 = p.matcher(m);
           if(m1.find()){
            String group []= m1.group().split("\\s");// split by space
            System.out.println(group[1]);// print the 2 position 
           }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多