正则表达式条件超前JavaScript

时间:2019-07-14 20:13:52

标签: javascript regex

我刚刚使用regex101创建了以下正则表达式。

([^,]*?)=(.*?)(?(?=, )(?:, )|(?:$))(?(?=[^,]*?=)(?:(?=[^,]*?=))|(?:$))

对于我的用例来说,它看起来很完美,因为它获得了逗号分隔的键和值,同时仍然保留了值中的逗号。

问题是,我想在Node.js(JavaScript)中使用此Regex,但是在regex101中编写整个Regex时,我将其设置为PCRE(PHP)。

JavaScript似乎不支持条件先行((?(?=...)()|())。

有没有办法让它在JavaScript中工作?


示例:

2个匹配项

第1组:id,第2组:1

第1组:name,第2组:bob

id=1, name=bob

3个匹配项

第1组:id,第2组:2

第1组:type,第2组:store

第1组:description,第2组:Hardwood Store

id=2, type=store, description=Hardwood Store

4个匹配项

第1组:id,第2组:4

第1组:type,第2组:road

第1组:name,第2组:The longest road name, in the entire world, and universe, forever

第1组:built,第2组:20190714

id=4, type=road, name=The longest road name, in the entire world, and universe, forever, built=20190714

3个匹配项

第1组:id,第2组:3

第1组:type,第2组:building

第1组:builder,第2组:Random Name, and Other Person, with help from Final Person

id=3, type=building, builder=Random Name, and Other Person, with help from Final Person

3 个答案:

答案 0 :(得分:1)

您可以使用

/([^,=\s][^,=]*)=(.*?)(?=(?:,\s*)?[^,=]*=|$)/g

请参见regex demo

详细信息

  • ([^,=\s][^,=]*)-第1组:
    • [^,=\s]-除,=和空格之外的字符
    • [^,=]*-除,=以外的零个或多个字符
  • =-一个=字符
  • (.*?)-第2组:除换行符以外的任何零个或多个字符,并且尽可能少
  • (?=(?:,\s*)?[^,=]*=|$)-正向超前,需要,和0+空格的可选序列,然后是,=以外的0+字符,然后是{{ 1}}或当前位置右边的字符串结尾

JS演示:

=

答案 1 :(得分:1)

还有另一种方法

\s*([^,=]*?)\s*=\s*((?:(?![^,=]*=)[\S\s])*)(?=[=,]|$)

https://regex101.com/r/J6SSGr/1

可读版本

 \s* 
 ( [^,=]*? )                   # (1), Key
 \s* = \s*                     #       =
 (                             # (2 start), Value
      (?:
           (?! [^,=]* = )
           [\S\s] 
      )*
 )                             # (2 end)
 (?= [=,] | $ )

PCRE最终版本

\s*([^,=]*?)\s*=\s*((?:(?!\s*[^,=]*=)[\S\s])*(?<![,\s]))\s*(?=[=,\s]|$)

https://regex101.com/r/slfMR1/1

 \s*                           # Wsp trim
 ( [^,=]*? )                   # (1), Key
 \s* = \s*                     # Wsp trim =  Wsp trim
 (                             # (2 start), Value
      (?:
           (?! \s* [^,=]* = )
           [\S\s] 
      )*
      (?<! [,\s] )                  # Wsp trim
 )                             # (2 end)
 \s*                           # Wsp trim
 (?= [=,\s] | $ )              # Field seperator

答案 2 :(得分:0)

也许这些表达式与您可能要设计的表达式有些接近:

([^=\n\r]*)=\s*([^=\n\r]*)\s*(?:,|$)

\s*([^=\n\r]*)=\s*([^=\n\r]*)\s*(?:,|$)

虽然不确定。

DEMO


如果要浏览/简化/修改该表达式,请在this demo的右上角进行解释。

const regex = /\s*([^=\n\r]*)=\s*([^=\n\r]*)\s*(?:,|$)/gm;
const str = `id=3, type=building, builder=Random Name, and Other Person, with help from Final Person

id=4, type=road, name=The longest road name, in the entire world, and universe, forever, built=20190714

id=2, type=store, description=Hardwood Store
id=1, name=bob

`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}

RegEx电路

jex.im可视化正则表达式:

enter image description here