【问题标题】:Java Regex Pattern doesn't do what the online testing tools sayJava 正则表达式模式并没有像在线测试工具所说的那样做
【发布时间】:2015-12-02 15:58:27
【问题描述】:

Java 中的正则表达式有问题。以下应匹配

2x 1 piece
63x 9 pieces
4x 1 piece
1 piece
23 pieces

使用这个正则表达式:

((\w+)x\s)*(\w+)\s*(\w*)

众所周知,我们必须在 Java 中转义字符串。我逃脱了正则表达式,并尝试使用这个:

String regex = "((\\w+)x\\s)*(\\w+)\\s*(\\w*)";

现在我的问题来了:正则表达式的所有在线服务都将我的模式标记为有效,除了用于 java 的模式。他们没有标记可能是假的,所以我看不出我的问题。这是我试图在 Java 中使用的代码:

String regex = "((\\w+)x\\s)*(\\w+)\\s*(\\w*)";
Pattern r = Pattern.compile(regex);
Matcher m = r.matcher(someClassWithMethods.text());
int multiplier=0;
int value= 0;
String supplement = "";
if (m.find( )) {
    multiplier= Integer.parseInt(m.group(2));
    value= Integer.parseInt(m.group(3));    
    supplement = m.group(4);
}

我调试了整个事情,看看发生了什么,所有变量都符合预期,但我仍然得到一个空组。这个正则表达式有什么问题?

编辑

由于 cmets,我已经更改了一些内容,并且我使用附加的 if 子句捕获了 NumberException。现在我仍然没有得到匹配的结果。那会是什么? 这是我的新代码:

String regex = "(?:(\\w+)x\\s)?(\\d+\\s+)(pieces?)";
Pattern r = Pattern.compile(regex);
Matcher m = r.matcher(quantityCell.text());
int quantityMultiplier = 0;
int quantity = 0;
String supplement = "";
if (m.find( )) {
    if(m.group(1) != null){ 
            quantityMultiplier = Integer.parseInt(m.group(1));
    }
    quantity = Integer.parseInt(m.group(2));    
    supplement = m.group(3);
}

【问题讨论】:

  • “空组”是什么意思?你得到的确切输出是什么?我试过了,对我来说效果很好......
  • 你的正则表达式实在是太低效了。为什么不使用(?:\\w+x\\s)?\\d+\\s+pieces?(未经测试的代码)
  • 我猜是 NumberFormatException?但是使用您的代码(如果而不是while),我认为它不会出现此异常。
  • 我的意思是匹配器组的值不是我期望的那样。如果我调试我的程序,我会收到一个具有以下值的组:[0, 1, -1, -1, -1, -1, 0, 1, 1, 1, -1, -1, -1, - 1、-1、-1、-1、-1、-1、-1]。组数组中的位置 1 很好,因为它是“1 件”中匹配的 1。但是“一块”这个词存储在哪里?好像不能正确匹配。
  • @TheRealNoXx:我不确定你想在这里做什么。如果您指出方法名称,我可以解释 Pattern 类中的代码,但您没有提及方法名称。如果你想让你的代码工作,你不需要将它调试到 Pattern 类中。向我们展示您的实际值不是您的期望值的测试用例。

标签: java regex expression


【解决方案1】:

你的正则表达式很奇怪:

  • \w+当你只对前两个实例中的数字感兴趣时,为什么要匹配“单词字符”?
  • ((\w+)x\s) 为什么这是一个捕获组?你不想要结果。
  • ((\w+)x\s)* 为什么会这样重复?你期待多个乘数吗?仅当存在多个乘数时,正则表达式才会捕获最后一个乘数。

让我们试试这个:

(?:(\d+)x\s)?(\d+)\s(\w*)

由于第一次捕获是可选的,如果不存在,它将是null,因此您需要检查它。

public static void main(String[] args) {
    test("2x 1 piece");
    test("63x 9 pieces");
    test("4x 1 piece");
    test("1 piece");
    test("23 pieces");
}
private static void test(String input) {
    String regex = "(?:(\\d+)x\\s)?(\\d+)\\s(\\w*)";
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(input);
    if (m.find()) {
        int multiplier = (m.group(1) != null ? Integer.parseInt(m.group(1)) : -1);
        int value = Integer.parseInt(m.group(2));
        String supplement = m.group(3);
        System.out.printf("%d, %d, '%s'%n", multiplier, value, supplement);
    }
}

输出

2, 1, 'piece'
63, 9, 'pieces'
4, 1, 'piece'
-1, 1, 'piece'
-1, 23, 'pieces'

【讨论】:

  • 这是我一直在等待的真正答案。万分感谢。我有一段时间没有使用正则表达式了。这就是为什么我没有考虑非捕获组的原因。我使用了 \w+ 因为我首先检查了输出而没有单独处理“x”字符,之后我忘记了更改它。祝你有美好的一天! :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-25
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-30
相关资源
最近更新 更多