javascript正则表达式选择带引号的字符串,但不选择转义引号
javascript regex to select quoted string but not escape quotes
原始字符串:
some text "some '"string'"right here "
想要获得:
"some '"string'"right here"
我正在使用以下正则表达式:
/'"(.*?)'"/g
使用解析器正确解析字符串
使用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);
不太安全的regex方法
不可能用惰性点匹配模式匹配所需的字符串,因为它将在第一个"
之前停止如果您知道您的字符串在带引号的子字符串之前永远不会有转义引号,并且如果您确定在双引号之前没有文字'
(并且这些条件对于安全使用正则表达式非常严格),则可以使用
/"([^"'']*(?:''.[^"'']*)*)"/g
查看regex演示
"
-匹配报价([^"'']*(?:''.[^"'']*)*)
-0个或多个[^"'']*
-0+非'
和非"
s(?:''.[^"'']*)*
-零个或多个''.
-任何转义符号[^"'']*
-0+非'
和非"
s
"
-后引号
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
安全正则表达式方法
作为@WiktorStribiżew答案的补充,有一种技术可以使用regex在正确的双引号处开始匹配。它包括匹配形式为的引用和未引用文本
/"(quoted)"|unquoted/g
正如你所看到的,引用的文本是由一个组匹配的,所以我们只考虑由match[1]
反向引用的文本。
Regex
/"([^"'']*(?:''.[^"'']*)*)"|[^"'']*(?:''.[^"'']*)*/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)
通用解决方案:
- 引号类型:单引号、双引号、反引号
- 检测每个引用的部分和引用类型
- 允许转义引号位于带引号的部分内
- 结果分为两组:<qType>(引号类型),<inQuotes>
(?<qType>["'`])(?&llt;inQuotes>(?:''''''1|.)*?)''1
或者,不带组命名:
([quot;'`])((?:''''''''1|.)*?)''1
您可以使用以下正则表达式:
/[^'']('".*?[^'']'")/g
[^'']
捕获任何不同于''的特征。所以"不会被捕获作为比赛的开始或结束。
为了在忽略任何简单转义引号的情况下从一个引号匹配到另一个引号('"
):
(:?[^'']|^)('"(:?.*?[^'']){0,1}'")
意味着(:?
分组的开始没有提取[^'']
匹配一个不是反斜杠的字符|
匹配前一个字符或^
是字符串的开始。(
提取分组的开始'"
查找引号(跟随非斜杠或字符串的开始),(:?.*?[^'']
匹配以非斜杠结尾的最短子字符串,){0,1}
零次或一次-这实际上意味着一次或空子字符串,后面跟着'"
引号。
编辑:Wiktor Stribiżew正确地指出,在我的初始回答中,字符串中有正则表达式项的更多情况将失败。例如CCD_ 27,该CCD_。为了避免这个特定的问题,你可以使用
(:?[^'']|^)((:?'''')*'"(:?.*?[^'']){0,1}(:?'''')*'")
但对于regex的实际兼容性,您需要参考Wiktor的答案。
- 下拉选择可自动更改第二个下拉选择
- 如何使用jQuery选择下拉列表的值
- jquery点击函数select&取消选择
- 在JavaScript中输出转义字符
- 转义符不能与innerHTML一起使用
- 是否有任何函数可以帮助转义 jQuery 选择器中包含的所有元字符?
- 使用属性等于选择器时转义元素名称中的方括号
- 在jQuery选择器中,这些不同的转义方括号的方法有什么区别
- Jquery转义选择器无法识别的表达式:[data route=search/child]
- 转义CSS选择器中的双引号
- j查询转义方括号以选择元素
- jquery选择器中的转义引号不起作用
- 使用jQuery的css选择器,转义特殊字符
- 为eval函数转义javascript撇号/引号,因此它仍然可以作为选择器使用
- javascript正则表达式选择带引号的字符串,但不选择转义引号
- 转义onclick生成的HTML具有带有CSS属性选择器的jQuery函数
- 如何转义查询选择器以支持 HTML5 ID
- 哪些字符需要在查询选择器中转义
- 转义脚本标签内的选择框选项(Chrome)
- 如何正确转义css/js属性选择器[attr=value]中的属性值