【问题标题】:Java regex help: capturing key-value pairsJava 正则表达式帮助:捕获键值对
【发布时间】:2012-07-13 18:33:57
【问题描述】:

我正在尝试从具有以下形式的字符串中捕获键值对:

a0=d235 a1=2314 com1="abcd" com2="a b c d"

this post 的帮助下,我能够编写以下捕获键值对的正则表达式:

Pattern.compile("(\\w*)=(\"[^\"]*\"|[^\\s]*)");

问题是这个模式中的第二组也捕获了引号,如下:

a0=d235
a1=2314
com1="abcd"
com2="a b c d"

如何排除引号?我想要这样的东西:

a0=d235
a1=2314
com1=abcd
com2=a b c d

编辑:

根据有无引号,可以通过捕获不同组中的值来实现上述目的。我正在为解析器编写此代码,因此出于性能原因,我试图提出一个可以返回同一组编号中的值的正则表达式。

【问题讨论】:

    标签: java regex parsing


    【解决方案1】:

    这个怎么样?想法是将最后一组分成 2 组。

    Pattern p = Pattern.compile("(\\w+)=\"([^\"]+)\"|([^\\s]+)");
    
    String test = "a0=d235 a1=2314 com1=\"abcd\" com2=\"a b c d\"";
    Matcher m = p.matcher(test);
    
    while(m.find()){
        System.out.print(m.group(1));
        System.out.print("=");
        System.out.print(m.group(2) == null ? m.group(3):m.group(2));
        System.out.println();
    }
    

    更新

    这是针对更新后的问题的新解决方案。这个正则表达式应用了积极的前瞻和后瞻来确保有一个引用而不实际解析它。这样,上面的第 2 组和第 3 组可以放在同一个组中(下面的第 2 组)。返回组 0 时无法排除引号。

    Pattern p = Pattern.compile("(\\w+)=\"*((?<=\")[^\"]+(?=\")|([^\\s]+))\"*");
    
    String test = "a0=d235 a1=2314 com1=\"abcd\" com2=\"a b c d\"";
    Matcher m = p.matcher(test);
    
    while(m.find()){
        print m.group(1);
        print "="
        println m.group(2);
    }
    

    输出

    a0=d235
    a1=2314
    com1=abcd
    com2=a b c d
    

    【讨论】:

    • 这类似于@burning_LEGION 的回答。我刚刚对我的问题进行了编辑;是否可以在同一组中捕获它们?
    • 不,不是全部在一个表达式中。您必须去掉每个右侧组中的引号。见这里:stackoverflow.com/questions/277547/…
    • @Dawood 可以在排除引号的情况下在单个组中捕获带引号和不带引号的字符串,但在排除引号时无法捕获所有内容(第 0 组)。
    • @user845279:这行得通……谢谢! lookahead 和 lookbehind 结构非常有用,但我还没有完全掌握它们。
    • 哇,我不认为这是可能的,但你的新更新真的很好用!但是,您确实想添加一个非捕获子句,因为现在您要保留 3 个组。这是您的最新消息:Pattern.compile("(\\w+)=\"*((?&lt;=\")[^\"]+(?=\")|(?:[^\\s]+))\"*");
    【解决方案2】:

    使用此正则表达式 (\w+)=(("(.+?)")|(.+?)(?=\s|$)) 键和值包含在正则表达式组中

    【讨论】:

    • 我尝试了类似的方法,但由于我正在为解析器编写此代码,因此我试图避免单独检查组,因为它会影响性能。您的代码将根据是否有引号将值存储在不同的组中。有没有办法将它存储在同一个组中?
    • 你能解释一下( .+?)是什么意思吗?
    • @LiSeeLeiCow-Q__Q 它捕获“与 ([^"]+)" 相同之前的所有符号
    猜你喜欢
    • 2019-11-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多