尽可能多地匹配组的正则表达式
Regular expression that matches group as many times as it can find
我写了一个正则表达式来匹配一些如下所示的标签:
@("hello, world" bold italic font-size="15")
我希望正则表达式匹配这些字符串:['hello, world', 'bold', 'italic', 'font-size="15"']
.
但是,只有这些字符串匹配:['hello, world', 'font-size="15"']
.
其他示例:
- (成功)
@("test") -> ["test"]
- (成功)
@("test" bold) -> ["test", "bold"]
- (失败)
@("test" bold size="15") -> ["test", "bold", 'size="15"']
我试过使用这个正则表达式:
\@\(\s*"((?:[^"\]|\.)*)"(?:\s+([A-Za-z0-9-_]+(?:\="(?:[^"\]|\.)*")?)*)\s*\)
分解版:
\@\(
\s*
"((?:[^"\]|\.)*)"
(?:
\s+
(
[A-Za-z0-9-_]+
(?:
\=
"(?:[^"\]|\.)*"
)?
)
)*
\s*
\)
正则表达式正在尝试
- 匹配序列的开头 (
$(
),
- 匹配带有转义字符的字符串,
- 匹配一些 (>= 1) 个空格,
- (可选,与(5)分组)匹配一个
=
符号,
- (可选,与(4)分组)匹配带有转义字符的字符串,
- 重复 (3) - (5)
- 匹配序列结尾 (
)
)
然而,这个正则表达式只匹配"hello, world"
和font-size="15"
。我怎样才能使它也匹配 bold
和 italic
,即多次匹配组 ([A-Za-z0-9-_]+(?:\="(?:[^"\]|\.)*")?)
?
预期结果:['"hello, world"', 'bold', 'italic', 'font-size="15']
P.S。使用 JavaScript 本机正则表达式
您需要一个两步解决方案:
- 使用
@\((?:\s*(?:"[^"\]*(?:\.[^"\]*)*"|[\w-]+(?:="?[^"\]*(?:\.[^"\]*)*"?)?))+\s*\)
、 提取子字符串
- 用
(?:"([^"\]*(?:\.[^"\]*)*)"|[\w-]+(?:="?[^"\]*(?:\.[^"\]*)*"?)?)
标记匹配项。
示例代码:
var re = /@\((?:\s*(?:"[^"\]*(?:\.[^"\]*)*"|[\w-]+(?:="?[^"\]*(?:\.[^"\]*)*"?)?))+\s*\)/g;
var re2 = /(?:"([^"\]*(?:\.[^"\]*)*)"|[\w-]+(?:="?[^"\]*(?:\.[^"\]*)*"?)?)/g;
var str = 'Text here @("hello, world" bold italic font-size="15") and here\nText there @("Welcome home" italic font-size="2345") and there';
var res = [];
while ((m = re.exec(str)) !== null) {
tmp = [];
while((n = re2.exec(m[0])) !== null) {
if (n[1]) {
tmp.push(n[1]);
} else {
tmp.push(n[0]);
}
}
res.push(tmp);
}
document.body.innerHTML = "<pre>" + JSON.stringify(res, 0, 4) + "</pre>";
我写了一个正则表达式来匹配一些如下所示的标签:
@("hello, world" bold italic font-size="15")
我希望正则表达式匹配这些字符串:['hello, world', 'bold', 'italic', 'font-size="15"']
.
但是,只有这些字符串匹配:['hello, world', 'font-size="15"']
.
其他示例:
- (成功)
@("test") -> ["test"]
- (成功)
@("test" bold) -> ["test", "bold"]
- (失败)
@("test" bold size="15") -> ["test", "bold", 'size="15"']
我试过使用这个正则表达式:
\@\(\s*"((?:[^"\]|\.)*)"(?:\s+([A-Za-z0-9-_]+(?:\="(?:[^"\]|\.)*")?)*)\s*\)
分解版:
\@\(
\s*
"((?:[^"\]|\.)*)"
(?:
\s+
(
[A-Za-z0-9-_]+
(?:
\=
"(?:[^"\]|\.)*"
)?
)
)*
\s*
\)
正则表达式正在尝试
- 匹配序列的开头 (
$(
), - 匹配带有转义字符的字符串,
- 匹配一些 (>= 1) 个空格,
- (可选,与(5)分组)匹配一个
=
符号, - (可选,与(4)分组)匹配带有转义字符的字符串,
- 重复 (3) - (5)
- 匹配序列结尾 (
)
)
然而,这个正则表达式只匹配"hello, world"
和font-size="15"
。我怎样才能使它也匹配 bold
和 italic
,即多次匹配组 ([A-Za-z0-9-_]+(?:\="(?:[^"\]|\.)*")?)
?
预期结果:['"hello, world"', 'bold', 'italic', 'font-size="15']
P.S。使用 JavaScript 本机正则表达式
您需要一个两步解决方案:
- 使用
@\((?:\s*(?:"[^"\]*(?:\.[^"\]*)*"|[\w-]+(?:="?[^"\]*(?:\.[^"\]*)*"?)?))+\s*\)
、 提取子字符串
- 用
(?:"([^"\]*(?:\.[^"\]*)*)"|[\w-]+(?:="?[^"\]*(?:\.[^"\]*)*"?)?)
标记匹配项。
示例代码:
var re = /@\((?:\s*(?:"[^"\]*(?:\.[^"\]*)*"|[\w-]+(?:="?[^"\]*(?:\.[^"\]*)*"?)?))+\s*\)/g;
var re2 = /(?:"([^"\]*(?:\.[^"\]*)*)"|[\w-]+(?:="?[^"\]*(?:\.[^"\]*)*"?)?)/g;
var str = 'Text here @("hello, world" bold italic font-size="15") and here\nText there @("Welcome home" italic font-size="2345") and there';
var res = [];
while ((m = re.exec(str)) !== null) {
tmp = [];
while((n = re2.exec(m[0])) !== null) {
if (n[1]) {
tmp.push(n[1]);
} else {
tmp.push(n[0]);
}
}
res.push(tmp);
}
document.body.innerHTML = "<pre>" + JSON.stringify(res, 0, 4) + "</pre>";