Azm*_*sov 56 javascript regex quotes escaping
从这个q/a,我推断出匹配给定正则表达式的所有实例不在引号内,是不可能的.也就是说,它无法匹配转义引号(例如:)"this whole \"match\" should be taken".如果有一种我不知道的方法,这将解决我的问题.
但是,如果没有,我想知道是否有任何可用于JavaScript的有效替代方案.我已经考虑了一下,但是没有任何优雅的解决方案可以在大多数(如果不是全部)情况下使用.
具体来说,我只需要使用.split()和.replace()方法的替代方法,但如果它可以更通用化,那将是最好的.
例如:
输入字符串:
+bar+baz"not+or\"+or+\"this+"foo+bar+
replace + with#,而不是引号内,将返回:
#bar#baz"not+or\"+or+\"this+"foo#bar#
Jen*_*ens 96
实际上,您可以匹配任何字符串中不是引号内的正则表达式的所有实例,其中每个开头引号再次关闭.如上例所示,您想要匹配\+.
这里的关键观察是,如果在其后面有偶数引号,则单词在引号之外.这可以建模为先行断言:
\+(?=([^"]*"[^"]*")*[^"]*$)
Run Code Online (Sandbox Code Playgroud)
现在,您不想计算转义报价.这变得有点复杂.而不是[^"]*,它推进到下一个引用,你需要考虑反斜杠和使用[^"\\]*.在您得到反斜杠或引号后,如果遇到反斜杠,则需要忽略下一个字符,否则前进到下一个未转义的引号.看起来像(\\.|"([^"\\]*\\.)*[^"\\]*").结合,你到达
\+(?=([^"\\]*(\\.|"([^"\\]*\\.)*[^"\\]*"))*[^"]*$)
Run Code Online (Sandbox Code Playgroud)
我承认这有点神秘.=)
zx8*_*x81 52
阿兹米索夫,复活这个问题,因为你说你在寻找any efficient alternative that could be used in JavaScript和any elegant solutions that would work in most, if not all, cases.
碰巧有一个没有提及的简单,通用的解决方案.
与替代方案相比,此解决方案的正则表达式非常简单:
"[^"]+"|(\+)
Run Code Online (Sandbox Code Playgroud)
我们的想法是匹配但忽略引号内的任何内容来中和该内容(在交替的左侧).在右侧,我们捕获+未被中和到第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);
Run Code Online (Sandbox Code Playgroud)
您可以使用相同的原则进行匹配或拆分.请参阅参考中的问题和文章,该文章还将指出代码示例.
希望这能为您提供一种非常通用的方法.:)
空字符串怎么样?
以上是展示该技术的一般答案.它可以根据您的具体需求进行调整.如果您担心文本可能包含空字符串,只需将字符串捕获表达式中的量词更改+为*:
"[^"]*"|(\+)
Run Code Online (Sandbox Code Playgroud)
见演示.
Escaped Quotes怎么样?
同样,以上是展示该技术的一般答案." 忽略此匹配 "正则表达式不仅可以根据您的需求进行优化,还可以添加多个表达式来忽略.例如,如果要确保已完全忽略转义引号,则可以先\\"|在其他两个引号之前添加一个替换,以匹配(并忽略)散乱转义的双引号.
接下来,在"[^"]*"捕获双引号字符串内容的部分中,您可以添加一个替换,以确保在它们"有机会变成结束标记之前匹配转义双引号,将其转换为"(?:\\"|[^"])*"
结果表达式有三个分支:
\\"匹配和忽略"(?:\\"|[^"])*"匹配和忽略(\+)匹配,捕捉和处理请注意,在其他正则表达式中,我们可以使用lookbehind更轻松地完成这项工作,但JS不支持它.
完整的正则表达式成为:
\\"|"(?:\\"|[^"])*"|(\+)
Run Code Online (Sandbox Code Playgroud)
参考
您可以分三步完成.
代码如下
// 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];
});
Run Code Online (Sandbox Code Playgroud)
如果你在设置后运行它
myString = '{:a "ab,cd, efg", :b "ab,def, egf,", :c "Conjecture"}';
Run Code Online (Sandbox Code Playgroud)
你应该得到
{:a "ab,cd, efg"
:b "ab,def, egf,"
:c "Conjecture"}
Run Code Online (Sandbox Code Playgroud)
它有效,因为在第1步之后,
myString = '{:a "0", :b "1", :c "2"}'
sideTable = ["ab,cd, efg", "ab,def, egf,", "Conjecture"];
Run Code Online (Sandbox Code Playgroud)
所以myString中唯一的逗号是外部字符串.第2步,然后将逗号转换为换行符:
myString = '{:a "0"\n :b "1"\n :c "2"}'
Run Code Online (Sandbox Code Playgroud)
最后,我们将仅包含数字的字符串替换为其原始内容.