繁体   English   中英

无法匹配除 ' 和 " 之外的任何字符的正则表达式

[英]Unable to match regex for any character except ' and "

我写了一个正则表达式来匹配字符串

{{AB.group.one}}:"eighth",{{AB.group.TWO}}:"third",{{attr1111}}:"fourth","fifth":{{attr_22_2qq2}},"sixth":{{AB.group.three}},{{ab.group.fourth}}:"seventh","ninth":{{attr1111}}}

正则表达式:

/[^'"]({{2}[a-zA-Z0-9$_].*?}{2})[^'"]/gi

打破上面的正则表达式:

  • [^'"] :以既不是'也不是"的字符开头。
  • ({{2}[a-zA-Z0-9$_].*?}{2}) :正好有 2 个{{ ,然后是a-zA-Z0-9$_范围内的任何字符。 之后,正好 2 }}
  • [^'"] : 除'"之外的任何字符。

下面的匹配不是完全匹配,而是捕获的组。 我将对捕获的组执行我的操作,因此为简单起见,我们可以将它们视为我们的匹配项。

预期匹配:

  • {{AB.group.one}}
  • {{AB.group.TWO}}
  • {{attr1111}}
  • {{attr_22_2qq2}}
  • {{AB.group.three}}
  • {{ab.group.fourth}}
  • {{attr1111}}}

结果匹配:

  • {{AB.group.TWO}}
  • {{attr1111}}
  • {{attr_22_2qq2}}
  • {{AB.group.three}}
  • {{attr1111}}}

正如您在下图中看到的{{AB.group.one}}{{ab.group.fourth}}不匹配。 我希望它们也能匹配它们。

正则表达式

我知道他们不匹配的原因。

{{AB.group.one}}不匹配的原因是因为[^'"]需要一个字符,除了'"而我没有提供一个。 如果我将[^'"]替换为["'"]* ,它会起作用,但在这种情况下"{{AB.group.one}}"也会匹配。

因此,问题陈述是匹配{{}}之前的任何字符(如果有的话),但该字符不能是'"

{{ab.group.fourth}}不匹配的原因是此匹配之前的字符 ie ,另一个匹配的一部分。 这只是我的猜测,原因可能是别的。 但如果我在{{AB.group.three}},{{ab.group.fourth}}之间包含任何字符(例如{{AB.group.three}}, {{ab.group.fourth}} ),然后模式匹配。 我不知道如何解决这个问题。

请帮我解决这两个问题。 谢谢你。

这是一种基于正则表达式的方法,似乎有效。 首先,我们可以将所有双引号术语串起来,然后用一个逗号分隔符替换逗号/冒号岛。 最后,以逗号分隔以生成术语数组。

 var input = "{{AB.group.one}}:\"eighth\",{{AB.group.TWO}}:\"third\",{{attr1111}}:\"fourth\",\"fifth\":{{attr_22_2qq2}},\"sixth\":{{AB.group.three}},{{ab.group.fourth}}:\"seventh\",\"ninth\":{{attr1111}}},\"blah\":\"stuff\",{{one}}:{{two}}"; var terms = input.replace(/\".*?\"/g, "").replace(/[,:]+/g, ",").split(","); console.log(terms);

你实际上非常接近你所拥有的。

 let input = '{{AB.group.one}}:"eighth",{{AB.group.TWO}}:"third",{{attr1111}}:"fourth","fifth":{{attr_22_2qq2}},"sixth":{{AB.group.three}},{{ab.group.fourth}}:"seventh","ninth":{{attr1111}}}' let regex = /(?<=[^'"]?)({{2}[a-zA-Z0-9$_].*?}{2})(?=[^'"]?)/gi; console.log(input.match(regex))

(?<=[^'"]?)是一个肯定的向后看。由于使用了否定字符集,我们正在检查匹配之前的字符不是 ' 或 "。 问号使这个可选 - 匹配零或前一个标记(否定字符集)之一。

(?=[^'"]?)是一个肯定的前瞻,并在表达式之后立即检查标记以确保它不是 ' 或 " (或者表达式之后没有标记)。

另一种选择,因为并非每个浏览器都支持后视:

 let input = '{{AB.group.one}}:"eighth",{{AB.group.TWO}}:"third",{{attr1111}}:"fourth","fifth":{{attr_22_2qq2}},"sixth":{{AB.group.three}},{{ab.group.fourth}}:"seventh","ninth":{{attr1111}}}' let regex = /(?:[^{'"])?({{2}[a-zA-Z0-9$_].*?}{2})(?:[^}'"])?/gi console.log([...input.matchAll(regex)].map(reg => reg[1]))

String.match() 在传递全局标志时失去对捕获组的引用,因此只返回“匹配”。 由于您正在使用({{2}[a-zA-Z0-9$_].*?}{2})创建捕获组,因此如果您只想确保括号表达式周围的字符不是引号,您可以只使用非捕获组进行这些可选检查。

(?:[^{'"])?是一个非捕获组,与(?:[^}'"])?

使用 String.matchAll,为每个匹配创建的 arrays 的第一个元素是整个匹配,第二个元素是第一个捕获组,等等。所以映射到[...input.matchAll(regex)]的逻辑就是从每场比赛中收集捕获组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM