[英]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.