正则表达式混淆

7
我对Java正则表达式的概念还不熟悉。请问有人能够告诉我下面这个字符串的正确匹配正则表达式吗?
String exp = "ABCD_123_abc"。
我使用的正则表达式是:
regExp = "([a-zA-Z]+)_([0-9]+)_([a-z]+)"
但以下代码的输出为"**未找到匹配项**"。
Public static void main()
{
   String exp = "ABCD_123_abc";
   String regExp = "([a-zA-Z]+)_([0-9]+)_([a-z]+)";
   Pattern pattern = Pattern.compile(exp);
   Matcher matcher = pattern.matcher(regExp);
   if(matcher.matches())
   {
     System.out.println("Match found");
   }
   else
   {
     System.out.println(" NO Match found");
   }


}

1
你在问题得到回答后修复了代码吗?这很令人困惑。 - MikeFHay
8个回答

12

问题是:您意外地交换了正则表达式模式和要检查的表达式的使用方法。

String exp = "ABCD_123_abc";
String regExp = "([a-zA-Z]+)_([0-9]+)_([a-z]+)";

应该使用

Pattern pattern = Pattern.compile(regExp);
Matcher matcher = pattern.matcher(exp);

Pattern.compile(String regex)函数接受正则表达式。

编辑

我很抱歉,我的第一个解决方案真的是一件绝不能做的事情:变量名与其值的含义相矛盾... 这意味着痛苦和眼泪,以及被愤怒的同事打击时的大喊大叫。对于这种罪行,没有合法的辩护...

编辑2 你可以通过Matcher.group(int)函数获取单个匹配组:

String matchedStringpart matcher.group(2);

注意:我将 2 作为参数使用:

  • 0 表示输入序列匹配
  • 1 表示第一个组(在这种情况下是 ABC
  • ...以此类推

如果您只需要 123 部分,我会重新编写正则表达式以便更清晰明了:

regExp = "[a-zA-Z]+_([0-9]+)_[a-z]+";

然而,在这种情况下,group() 必须使用 1 调用,因为现在第一个(也是唯一的)匹配组是第一个组:

String matchedStringpart matcher.group(1);

4
我认为实际上使用Pattern.compile(regExp)更合理,这意味着OP颠倒了编译和匹配器语句,但本质上是相同的错误。 - FrankieTheKneeMan
2
解决了,但是现在这些名字非常误导人。 - Junuxx
1
@all 对,有时候大脑就是个古怪的东西 :) 我假设如果字符串需要交换,我可以交换它的句柄(懒惰,这意味着要更改的字符更少)- 不知何故,我完全忽略了变量名称的语义。这是绝不能做的... - ppeterka
非常感谢您提供的解决方案。 - Sonia
2
+1 不是为了回答,而是为了“没有对这种罪行进行有效的辩护......”我希望我的同事们能够像这样对自己的错误做出回应。 - AmericanUmlaut
@AmericanUmlaut +1 给你的 +1。免责声明:我曾经很久以前调试过一个名为 isAvailable 的变量,它表现得很奇怪。我想,你可以从这里结束故事 :) :) - ppeterka

8

您没有编译正则表达式。您需要

Pattern pattern = Pattern.compile(regExp);
Matcher matcher = pattern.matcher(exp);

即上述代码混淆了正则表达式和输入字符串。你实际上的正则表达式是正确的。

5

你的正则表达式完全正确

问题在于你在代码中交换了expregExp。函数compile的参数是一个正则表达式,而函数matcher需要匹配的表达式。


4

您(编辑过的)正则表达式是正确的。

如果您想提取123,可以使用matcher.group(2)。该方法只能在matchesfind之后调用。matcher.group(n)返回第n个捕获组。捕获组是您正则表达式中用括号括起来的部分。matcher.group(0)返回匹配的字符串。

示例

if(matcher.matches()) {
  System.out.println(matcher.group(0));
  System.out.println(matcher.group(1));
  System.out.println(matcher.group(2));
  System.out.println(matcher.group(3));
}

输出
 ABCD_123_abc
 ABCD
 123
 abc

2

if(exp.matches(regExp))

这个语句已经足够了。除非你有其他需求,否则不需要使用Pattern/Matcher。


1
这个模式可以匹配任意数量的大写或小写字母,然后是下划线,然后是任意数量的数字,再然后是下划线,最后是任意数量的大写或小写字母。如果你想更加具体,可以使用{n}代替+来匹配特定数量的字符。
public static void main(String[] args) {
    final String myString = "ABCD_123_abc";
    final Pattern p = Pattern.compile("^[A-Za-z]++_(\\d++)_[A-Za-z]++$");
    final Matcher matcher = p.matcher(myString);
    if (matcher.matches()) {
        System.out.println(matcher.group(1));
    }
}

1
在这种情况下,如果您想检索123,请使用以下代码:
 System.out.println(matcher.group(2));

这将输出:123 你的正则表达式完全没问题。

0

首先编译正则表达式,然后使用匹配器进行比较。

Pattern pattern = Pattern.compile(regExp);
Matcher matcher = pattern.matcher(exp);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接