Javascript 正则表达式匹配所有不在引号内的实例
从中,我推断匹配给定正则表达式的所有实例(不在引号内)是不可能的。也就是说,它不能匹配转义引号(例如:Javascript 正则表达式匹配所有不在引号内的实例,javascript,regex,escaping,quotes,Javascript,Regex,Escaping,Quotes,从中,我推断匹配给定正则表达式的所有实例(不在引号内)是不可能的。也就是说,它不能匹配转义引号(例如:“应该采用整个匹配”)。如果有一种我不知道的方法可以解决我的问题 然而,如果没有,我想知道是否有任何有效的替代方案可以在JavaScript中使用。我已经考虑过一点了,但是没有任何优雅的解决方案能够在大多数情况下(如果不是全部的话)都有效 具体地说,我只需要使用.split()和.replace()方法的替代方法,但是如果它可以更一般化,那将是最好的 例如: 输入字符串:+bar+baz“not
“应该采用整个匹配”
)。如果有一种我不知道的方法可以解决我的问题
然而,如果没有,我想知道是否有任何有效的替代方案可以在JavaScript中使用。我已经考虑过一点了,但是没有任何优雅的解决方案能够在大多数情况下(如果不是全部的话)都有效
具体地说,我只需要使用.split()和.replace()方法的替代方法,但是如果它可以更一般化,那将是最好的
例如:输入字符串:
+bar+baz“not+”或\“+或+\”this+”foo+bar+
将+替换为#,而不是内部引号,将返回:
// Step 1
var sideTable = [];
myString = myString.replace(
/"(?:[^"\\]|\\.)*"/g,
function (_) {
var index = sideTable.length;
sideTable[index] = _;
return '"' + index + '"';
});
// Step 2, replace commas with newlines
myString = myString.replace(/,/g, "\n");
// Step 3, swap the string bodies back
myString = myString.replace(/"(\d+)"/g,
function (_, index) {
return sideTable[index];
});
如果在设置后运行
myString = '{:a "ab,cd, efg", :b "ab,def, egf,", :c "Conjecture"}';
你应该
{:a "ab,cd, efg"
:b "ab,def, egf,"
:c "Conjecture"}
它起作用了,因为在第一步之后
myString = '{:a "0", :b "1", :c "2"}'
sideTable = ["ab,cd, efg", "ab,def, egf,", "Conjecture"];
因此myString中唯一的逗号是字符串外部。步骤2,然后将逗号转换为换行符:
myString = '{:a "0"\n :b "1"\n :c "2"}'
最后,我们将只包含数字的字符串替换为其原始内容。实际上,您可以为任何字符串匹配不包含引号的正则表达式的所有实例,其中每个开头引号都会再次关闭。比如说,正如上面的示例中所示,您希望匹配
\+
这里的关键观察是,如果一个单词后面有偶数个引号,那么它就在引号之外。这可以建模为前瞻性断言:
\+(?=([^"]*"[^"]*")*[^"]*$)
现在,您希望不计算转义引号。这会变得更复杂一些。而不是<>代码> [^ ] */COD>,它进入下一个引用,您还需要考虑反斜杠,并使用<代码> [^ \\\**/COD>。到达反斜杠或引号后,如果遇到反斜杠,则需要忽略下一个字符,或者前进到下一个未替换的引号。这看起来像是(\\.\”([^“\\]*\\\)*[^“\\]*”
。加起来,你就到了
\+(?=([^"\\]*(\\.|"([^"\\]*\\.)*[^"\\]*"))*[^"]*$)
我承认这有点神秘 Azmisov,重新提出这个问题,因为您说您正在寻找
任何可以在JavaScript中使用的有效替代方案
,以及任何可以在大多数(如果不是全部)情况下使用的优雅解决方案
碰巧有一个简单的、通用的解决方案没有提到
与备选方案相比,此解决方案的正则表达式非常简单:
"[^"]+"|(\+)
我们的想法是匹配,但忽略引号中的任何内容,以中和该内容(在替换的左侧)。在右侧,我们捕获所有未中和到组1中的+
,替换函数检查组1。以下是完整的工作代码:
<script>
var subject = '+bar+baz"not+these+"foo+bar+';
var regex = /"[^"]+"|(\+)/g;
replaced = subject.replace(regex, function(m, group1) {
if (!group1) return m;
else return "#";
});
document.write(replaced);
看
转义引号呢?
同样,以上是展示该技术的一般答案。“ignorethismatch”正则表达式不仅可以根据您的需要进行优化,还可以添加多个要忽略的表达式。例如,如果要确保已充分忽略转义引号,可以先在其他两个引号前面添加一个替代项\\\“
,以便匹配(并忽略)散乱的转义双引号
接下来,在捕获双引号字符串内容的部分“[^”]*”
中,您可以添加一个替代项,以确保转义的双引号在它们的“
有机会变为结束哨兵,将其变为”(?:\\“|[^]”)*“
结果表达式有三个分支:
\\”
匹配并忽略“(?:\\“\[^”])*”
匹配并忽略(\+)
要匹配,捕获和处理\\"|"(?:\\"|[^"])*"|(\+)
见和
参考
尽管zx81给出的答案似乎是性能最好且清晰的答案,但它需要以下修复来正确捕获转义引号:
var subject = '+bar+baz"not+or\\"+or+\\"this+"foo+bar+';
及
还有前面提到的“group1==未定义”或“!group1”。
特别是2。实际上,考虑原始问题中提出的所有问题似乎都很重要
但是应该提到的是,此方法隐式要求字符串在未转义引号对之外不包含转义引号。谢谢!我认为这是不可能的。我100%的理解这个理论,大约60%的正则表达式,当我自己写的时候,我的理解率降到了0%。哦,也许有一天吧。嘿,有没有办法让正则表达式与JavaScript的.split()方法一起工作?它似乎忽略了全局标志…不管怎样,只是忘了在所有的括号中加上
?:
:\+(?=(?:[^“\\]*(?:\.\.\124;”(?:[^“\]*\.*”*[^“\]*”)[^“]*$)
尝试在项目中使用此选项,但失败。我发现原因是两个单引号内有一个双引号“
…这将导致字符串中双引号的数量为奇数请大家看看@zx81在其答案中建议的解决方案。如果可以使用+1作为优雅的非正则表达式解决方案,那么它更易于编写,并且具有更好的性能。不过,对于我所做的事情来说,正则表达式要灵活一些。这种方法实际上比@Jens建议的前瞻性方法要好。它更容易编写,性能也更好。我没有注意到并使用了前瞻性方法,直到我遇到了一个性能问题,为了匹配150万条文本,在这种方法启动时,前瞻性方法使用了大约90秒
var subject = '+bar+baz"not+or\\"+or+\\"this+"foo+bar+';
var regex = /"(?:[^"\\]|\\.)*"|(\+)/g;