原始字符串:
some text "some \"string\"right here "
想要获得:
"some \"string\"right here"
我正在使用以下正则表达式:
/\"(.*?)\"/g
答案 0 :(得分:2)
使用JavaScript正则表达式,无法以正确的双引号开始匹配。您将匹配转义的一个,或者在引用之前的文字\
之后您将无法匹配正确的双引号。因此,最安全的方法是使用解析器。这是一个样本:
var s = "some text \\\"extras\" some \\\"string \\\" right\" here \"";
console.log("Incorrect (with regex): ", s.match(/"([^"\\]*(?:\\.[^"\\]*)*)"/g));
var res = [];
var tmp = "";
var in_quotes = false;
var in_entity = false;
for (var i=0; i<s.length; i++) {
if (s[i] === '\\' && in_entity === false) {
in_entity = true;
if (in_quotes === true) {
tmp += s[i];
}
} else if (in_entity === true) { // add a match
in_entity = false;
if (in_quotes === true) {
tmp += s[i];
}
} else if (s[i] === '"' && in_quotes === false) { // start a new match
in_quotes = true;
tmp += s[i];
} else if (s[i] === '"' && in_quotes === true) { // append char to match and add to results
tmp += s[i];
res.push(tmp);
tmp = "";
in_quotes = false;
} else if (in_quotes === true) { // append a char to the match
tmp += s[i];
}
}
console.log("Correct results: ", res);
&#13;
由于它将在第一个"
之前停止,因此无法将所需的字符串与延迟点匹配模式匹配。 如果您知道您的字符串在引用的子字符串之前永远不会有转义引号,并且如果您确定双引号之前没有文字\
(并且这些条件非常严格,请使用安全的正则表达式,你可以使用
/"([^"\\]*(?:\\.[^"\\]*)*)"/g
请参阅regex demo
"
- 匹配报价([^"\\]*(?:\\.[^"\\]*)*)
- 0或更多序列
[^"\\]*
- 0+非 - \
和非"
(?:\\.[^"\\]*)*
- 零个或多个序列
\\.
- 任何转义符号[^"\\]*
- 0+非 - \
和非"
"
- 尾随报价JS演示:
var re = /"([^"\\]*(?:\\.[^"\\]*)*)"/g;
var str = `some text "some \\"string\\"right here " some text "another \\"string\\"right here "`;
var res = [];
while ((m = re.exec(str)) !== null) {
res.push(m[1]);
}
document.body.innerHTML = "<pre>" + JSON.stringify(res, 0, 4) + "</pre>"; // Just for demo
console.log(res); // or another result demo
&#13;
答案 1 :(得分:0)
您可以使用此正则表达式:
/[^\\](\".*?[^\\]\")/g
[^\\]
抓住任何与...不同的特征。因此,“不会成为比赛的开始或结束。
答案 2 :(得分:0)
为了在引用与引用匹配的同时忽略任何简单的转义引号(\"
):
(:?[^\\]|^)(\"(:?.*?[^\\]){0,1}\")
意味着(:?
开始分组,没有提取[^\\]
匹配一个不是反斜杠|
的字符匹配前一个字符串或^
字符串的开头。 (
提取分组的开始\"
找到引号(跟随非斜杠或字符串的开头),(:?.*?[^\\]
匹配以无斜线结尾的最短子字符串,){0,1}
零次或一次 - 这实际上意味着一次或一个空的子字符串,后跟\"
一个引号。
修改强>
WiktorStribiżew正确地指出,在我的初始答案中,字符串中使用正则表达式术语的更多案例将会失败。例如\\"
,在您的情况下应与"
类似。要避免此特定问题,您可以使用
(:?[^\\]|^)((:?\\\\)*\"(:?.*?[^\\]){0,1}(:?\\\\)*\")
但是对于实际的正则表达式兼容性,您需要参考Wiktor的答案。
答案 3 :(得分:0)
补充@WiktorStribiżew's answer,有一种技术可以使用正则表达式在正确的双引号处开始匹配。它包括以下形式匹配引用和未引用的文本:
/"(quoted)"|unquoted/g
正如您所看到的,引用的文字由一个组匹配,因此我们只考虑match[1]
反向引用的文字。
/"([^"\\]*(?:\\.[^"\\]*)*)"|[^"\\]*(?:\\.[^"\\]*)*/g
var regex = /"([^"\\]*(?:\\.[^"\\]*)*)"|[^"\\]*(?:\\.[^"\\]*)*/g;
var s = "some text \\\"extras\" some \\\"string \\\" right\" here \"";
var match;
var res = [];
while ((match = regex.exec(s)) !== null) {
if (match.index === regex.lastIndex)
regex.lastIndex++;
if( match[1] != null )
res.push(match[1]); //Append to result only group 1
}
console.log("Correct results (regex technique): ",res)