JS中的命名组和OR运算符

时间:2019-02-21 15:20:22

标签: javascript node.js regex pcre

我正在尝试匹配2h30m,24h,1d20h30s之类的字符串,并使用命名组提取每个段。听起来很容易且可行,这是如果您将PCRE与正则表达式一起使用,如下所示:

5|0|21|https://d50.eng.domain.com:1050/newgenmashup/v1/mashup/|1D4E8B05B21570719C10066C4E15360C|com.contactual.client.SFService|triggerEvent|java.lang.String|com.contactual.client.model.GenericXmlData|java.util.TreeMap|tenant~~pagent2|com.contactual.client.model.GenericXmlData/2918165779||353-726-6515|no|offered|PHONE|in|563|PavanInboundQueue|1|465| <UserData>
<param name = "@pri"><![CDATA[100]]></param>
<param name="callingName"><![CDATA[ 1234567366]]></param>
<param name="cha"><![CDATA[3537266515]]></param>
<param name="channelName"><![CDATA[353-726-6515]]></param>
<param name="cnt"><![CDATA[0]]></param>
<param name="con"><![CDATA[0]]></param>
<param name="med"><![CDATA[T]]></param>
<param name="otim"><![CDATA[1550070210]]></param>
<param name="pho"><![CDATA[ 1234567366]]></param>
<param name="phoneNum"><![CDATA[ 1234567366]]></param>
<param name="priority"><![CDATA[50]]></param>
<param name="que"><![CDATA[vcclondon~~queue~~phone~~563]]></param>
<param name="queueDirection"><![CDATA[in]]></param>
<param name="tenantName"><![CDATA[vcclondon]]></param>
<param name="tenantRecServer"><![CDATA[d50]]></param>
<param name="tenantSkillName"><![CDATA[PavanInboundQueue]]></param>
<param name="tim"><![CDATA[1550070210]]></param>
<param name="tok"><![CDATA[465]]></param>
<param name="queuedTime"><![CDATA[0]]></param>
<param name="ani"><![CDATA[ 1234567366]]></param>
<param name="interaction_guid"><![CDATA[int-168e76257e3-r5tEbRqwNR7hBd7jmuvwnsxG9-phone-00-vcclondon]]></param>
<param name="transaction_id"><![CDATA[465]]></param>
<param name="notes"><![CDATA[]]></param>
<param name="callbackTimeMs"><![CDATA[]]></param>
<param name="ctl_userdata"><![CDATA[[doNotCallSelected\!false][donotcallSelected\!false]]]></param>
</UserData>|java.util.TreeMap/1575826026|1|2|3|4|3|5|6|7|8|9|0|0|0|0|10|0|0|0|10|0|11|0|12|0|13|10|0|10|1|0|0|0|14|15|16|17|18|10|10|0|19|20|21|0|0|

regexr上的完整示例,您可以在右上角的PCRE和Javascript引擎之间切换。

问题是它在javascript中不起作用,我不知道为什么。我的猜测是它与OR运算符与命名组之间的交互有关,因为在使用javascript时,它仅返回命名组之一

问题是为什么?以及是否有任何方法可以使用javascript

1 个答案:

答案 0 :(得分:1)

似乎|应该替换为?以捕获一行中的多个组(使用|时,只能捕获一行中的最后一个组)。并且我们需要添加一个非空断言以防止空字符串匹配。另外,值得插入一些?:以使某些组不被捕获。

'use strict';

const str = `
2h30m
24h
1d20h30s
`;

const re = /^(?=.+)(?:(?:(?<d>[0-9]+)d)?(?:(?<h>[0-9]+)h)?(?:(?<m>[0-9]+)m)?(?:(?<s>[0-9]+)s)?(?:(?<ms>[0-9]+)ms)?)+$/gm;

let result;

while (result = re.exec(str)) console.log(result.groups);

如果您的Node.js(或浏览器)支持新的matchAll()方法,也可以通过以下方式实现:

'use strict';

const str = `
2h30m
24h
1d20h30s
`;

const re = /^(?=.+)(?:(?:(?<d>[0-9]+)d)?(?:(?<h>[0-9]+)h)?(?:(?<m>[0-9]+)m)?(?:(?<s>[0-9]+)s)?(?:(?<ms>[0-9]+)ms)?)+$/gm;

console.log(Array.from(str.matchAll(re), ({ groups }) => groups));