匹配报价包装javascript中的字符串与正则表达式

时间:2017-05-07 12:36:29

标签: javascript regex

我需要javascript的正则表达式才能匹配

"{any group of chars}" <-- where that last " is not preceeded by a \

的示例:

... foo "bar" ...  => "bar"
... foo"bar\"" ... => "bar\""
... foo "bar" ...  goo"o"ooogle "t\"e\"st"[] => ["bar", "o", "t\"e\"st"]

实际字符串会更长,可能包含多个匹配项,也可能包含空格或正则表达式特殊字符。

我已经开始尝试分解语法,但不是强大的正则表达式我自己被卡住了很快但我确实得到了匹配一切除了匹配包含\“(我想)的情况..

https://regex101.com/r/sj4HXw/1

更新:

更多关于我的情况......

此正则表达式将用于我的博客帖子中嵌入的代码块中的“语法高亮”字符串,因此真实世界的示例可能看起来像这样......

<pre id="test" class="code" data-code="csharp">
   if (ConfigurationManager.AppSettings["LogSql"] == "true")
</pre>

我正在使用以下javascript来实现亮点..

var result = $("#test").text().replace(/"[^"\\]*(?:\\[\s\S][^"\\]*)*"/g, "<span class=\"string\">$1</span>");
$("#test").html(result);

由于某种原因,即使在这种情况下使用建议的答案(至少到目前为止),我也会得到奇怪的结果。

这样可行,但由于某种原因,它会将值$ 1而不是实际匹配。

3 个答案:

答案 0 :(得分:4)

首先优先考虑转义字符:

"(\\.|[^"])*"

https://regex101.com/r/sj4HXw/2

答案 1 :(得分:2)

简单方案(如在OP中)

您可以在此处使用的最有效的正则表达式(根据unroll-the-loop principle编写)是

"[^"\\]*(?:\\[\s\S][^"\\]*)*"

请参阅regex demo

<强>详情:

  • " - 匹配第一个"
  • [^"\\]* - 除"\
  • 以外的0个字符
  • (?:\\[\s\S][^"\\]*)* - zer或更多次出现:
    • \\[\s\S] - 前面有[\s\S]的任何字符(\
    • [^"\\]* - 除"\
    • 以外的0个字符
  • " - 结束"

用法:

// MATCHING
var rx = /"[^"\\]*(?:\\[\s\S][^"\\]*)*"/g;
var s = '    ... foo "bar" ...  goo"o"ooogle "t\\"e\\"st"[]';
var res = s.match(rx);
console.log(res);

// REPLACING
console.log(s.replace(rx, '<span>$&</span>'));

更高级的方案

如果在有效匹配之前存在转义"\之前有" s,则上述方法将无效。您需要匹配这些\并捕获您需要的子字符串。

/(?:^|[^\\])(?:\\{2})*("[^"\\]*(?:\\[\s\S][^"\\]*)*")/g
 ^^^^^^^^^^^^^^^^^^^^^^                             ^

请参阅another regex demo

用法:

// MATCHING
var rx = /(?:^|[^\\])(?:\\{2})*("[^"\\]*(?:\\[\s\S][^"\\]*)*")/g;
var s = '    ... \\"foo "bar" ...  goo"o"ooogle "t\\"e\\"st"[]';
var m, res=[];
while (m = rx.exec(s)) {
  res.push(m[1]);
}
console.log(res);

// REPLACING
console.log(s.replace(/((?:^|[^\\])(?:\\{2})*)("[^"\\]*(?:\\[\s\S][^"\\]*)*")/g, '$1<span>$2</span>'));

主模式包含捕获括号,并在开头添加:

  • (?:^|[^\\]) - 字符串的开头或\
  • 的任何字符
  • (?:\\{2})* - 0次出现双反斜杠。

答案 2 :(得分:0)

这应该这样做:

"(\\[\s\S]|[^"\\])*"

这是Wiktor和Taufik的其他答案的混合。