Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 这个正则表达式不正确吗?没有找到匹配项_Java_Regex - Fatal编程技术网

Java 这个正则表达式不正确吗?没有找到匹配项

Java 这个正则表达式不正确吗?没有找到匹配项,java,regex,Java,Regex,我试图通过如下格式的字符串进行解析,除了使用更多值: Key1=value,Key2=value,Key3=value,Key4=value,Key5=value,Key6=value,Key7=value 正则表达式 ((键1)=(.*),((键2)=(.*),((键3)=(.*),((键4)=(.*),((键5)=(.*),((键6)=(.*),((键7)=(.*)) 在实际字符串中,键/值的数量大约是原来的两倍,但为了简洁起见,我将其保持简短。我把它们放在括号里,这样我就可以分组叫它们了。

我试图通过如下格式的字符串进行解析,除了使用更多值:

Key1=value,Key2=value,Key3=value,Key4=value,Key5=value,Key6=value,Key7=value

正则表达式

((键1)=(.*),((键2)=(.*),((键3)=(.*),((键4)=(.*),((键5)=(.*),((键6)=(.*),((键7)=(.*))


在实际字符串中,键/值的数量大约是原来的两倍,但为了简洁起见,我将其保持简短。我把它们放在括号里,这样我就可以分组叫它们了。我存储的键是常量,它们永远都是一样的。问题是,它永远不会找到一个没有意义的匹配项(除非正则表达式是错误的)

看起来您最好这样做:

String[] pairs = data.split(",");

然后一次解析一个键/值对

如果你知道你总是有7个,那么阻力最小的方法就是

^Key1=(.+),Key2=(.+),Key3=(.+),Key4=(.+),Key5=(.+),Key6=(.+),Key7=(.+)$
试试看吧


我非常确定有一种更好的方法来解析这个东西,它是通过.find()而不是.matches(),我想我会推荐这种方法,因为它允许您一次将字符串向下移动一个key=value对。它将您带入整个“贪婪”评估讨论。

它本身并没有错,但它需要大量回溯,这可能会导致正则表达式引擎退出。我会尝试其他地方建议的拆分,但如果您真的需要使用正则表达式,请尝试使其非贪婪

((Key1)=(.*?)),((Key2)=(.*?)),((Key3)=(.*?)),((Key4)=(.*?)),((Key5)=(.*?)),((Key6)=(.*?)),((Key7)=(.*?))
要理解为什么它需要如此多的回溯,首先要理解这一点

Key1=(.*),Key2=(.*)
适用于

Key1=x,Key2=y
Java的正则表达式引擎将第一个
(.*)
匹配到
x,Key2=y
,然后尝试从右侧剥离字符,直到它可以获得正则表达式其余部分的匹配:
,Key2=(.*)
。它实际上是在问

  • 是否匹配
    ,键2=(.*)
    ,因此请尝试
  • “y”
    是否匹配
    ,键2=(.*)
    ,因此请重试
  • “=y”
    是否匹配
    ,键2=(.*)
    ,因此请重试
  • “2=y”
    是否匹配
    ,键2=(.*)
    ,因此请重试
  • “y2=y”
    是否匹配
    ,键2=(.*)
    ,因此请重试
  • “ey2=y”
    是否匹配
    ,Key2=(.*)
    ,因此请重试
  • “Key2=y”
    是否匹配
    ,Key2=(.*)
    ,因此请重试
  • ”,Key2=y“
    是否匹配
    ,Key2=(*)
    ,是,因此第一个
    *
    “x”
    ,第二个是
    “y”
  • 编辑:

    在Java中,非贪婪限定符改变了一些事情,因此它开始尝试不匹配任何内容,然后从那里开始构建

  • “x,Key2=(.*)”
    是否匹配
    ,Key2=(.*)
    ,请不要尝试
  • 是否
    ”,键2=(.*)”
    匹配
    ,键2=(.*)
    ,是

  • 所以当你有7个键时,不需要取消匹配其中的6个键,其中包括取消匹配的5个键,其中包括取消匹配的4个键。。。。它可以在一次向前传递输入的过程中完成它的工作。

    您的正则表达式正在为我工作

    如果你总是得到一个非法的州例外,我想说你正在尝试做一些类似的事情:

    matcher.group(1);
    
    没有调用find()方法

    在尝试获取组之前,需要调用该方法(否则调用group()方法将处于非法状态)

    尝试一下:

        String test = "Key1=value,Key2=value,Key3=value,Key4=value,Key5=value,Key6=value,Key7=value";
    
        Pattern pattern = Pattern.compile("((Key1)=(.*)),((Key2)=(.*)),((Key3)=(.*)),((Key4)=(.*)),((Key5)=(.*)),((Key6)=(.*)),((Key7)=(.*))");
    
        Matcher matcher = pattern.matcher(test);
    
        matcher.find();
    
        System.out.println(matcher.group(1));
    

    根据上面的评论判断,听起来像是在创建模式和匹配器对象,并将匹配器与目标字符串相关联,但实际上并没有应用正则表达式。这是一个很常见的错误。以下是完整的顺序:

    String regex = "Key1=(.*),Key2=(.*)"; // etc.
    Pattern p = Pattern.compile(regex);
    Matcher m = p.matcher(targetString);
    // Now you have to apply the regex:
    if (m.find())
    {
      String value1 = m.group(1);
      String value2 = m.group(2);
      // etc.
    }
    
    您不仅必须调用
    find()
    matches()
    (或
    lookingAt()
    ,而且从来没有人使用过该函数),您应该始终在
    if
    while
    语句中调用它——也就是说,在调用任何方法(如
    group()之前,您应该确保正则表达式实际工作
    要求匹配器处于“匹配”状态

    还请注意,大多数括号都没有。它们是不必要的,省略它们可以使(1)阅读正则表达式和(2)跟踪组号更容易

    有些人在遇到问题时会想:“我知道,我会用 正则表达式。“现在他们有两个问题。”杰米·扎温斯基

    最简单的解决方案是最稳健的

    final String data = "Key1=value,Key2=value,Key3=value,Key4=value,Key5=value,Key6=value,Key7=value";
    final String[] pairs = data.split(",");
    for (final String pair: pairs)
    {
       final String[] keyValue = pair.split("=");
       final String key = keyValue[0];
       final String value = keyValue[1];
    }
    

    我不想说没有正则表达式可以解决这个问题,但它的编写(更重要的是,对于下一个需要处理代码的人来说)可能比它的价值更复杂。使用正则表达式,我能得到的最接近的结果是,如果在匹配的字符串中附加一个终端逗号,即,而不是:

    "Key1=value1,Key2=value2"
    
    您可以附加一个逗号,以便:

    "Key1=value1,Key2=value2,"
    
    然后,最接近我的正则表达式是:
    “(?:(\\w+?)=(\\S+?),)?+”
    …但是如果这些值有逗号,这就不太管用了

    你可以试着从那里继续调整正则表达式,但我发现的问题是贪婪的量词和不情愿的量词之间的行为存在冲突。您必须为值指定一个捕获组,该值相对于逗号贪婪,直到最后一个逗号,然后是由单词字符后跟等号(下一个值)组成的非捕获组。如果您匹配序列中的最后一个值,则最后一个非捕获组必须是可选的,也许它自己也不愿意。复杂

    相反,我的建议是在
    “=”
    上拆分字符串。您可以这样做,因为这些值可能不允许包含等号字符

    现在您将有一组子字符串,每个子字符串都是一组字符,组成一个值,字符串中的最后一个逗号,后跟一个键。您可以使用
    String.lastIndexOf(',')
    轻松找到每个子字符串中的最后一个逗号

    特别处理第一个子字符串和最后一个子字符串(因为第一个子字符串没有预先指定的值,并且