正则表达式:方括号之间的符号有限

时间:2016-10-25 23:30:58

标签: javascript regex

字符串示例:Text sample [79zd915j][fxC1bPYW][asd12233]

结果我想要一个数组:["[79bl9F5j]", "[fKCebPYW]", "[asd12233]"]

我做了解决方案,但不知何故,在括号内的8个符号后停止并且到达字符串的末尾。

我的正则表达式:/(\[[\w\d]{8}\])+/.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]")

我的结果:["[79bl9F5j][fKCebPYW][asd12233]", "[asd12233]"]

帮我写一个正确的,请告诉我,我的正则表达式有什么问题?为什么它不像我预期的那样工作?

3 个答案:

答案 0 :(得分:1)

(\[\w{8}\])

就够了。参见演示。

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

+符号导致问题。它将匹配整个[79zd915j][fxC1bPYW][asd12233]但只捕获组1中的最后一个[asd12233],因为正则表达式引擎仅记住连续组时的最后一个组匹配

答案 1 :(得分:1)

第一个问题+。这意味着重复一次 。所以这符合:

[abcdefgh][abcdefgh][abcdefgh]以及[abcdefgh][abcdefgh][abcdefgh] ...

例如

var str = "Text sample [79zd915j][fxC1bPYW]xxx[asd12233]";
var regex = /(\[[\w\d]{8}\])+/;
var res = regex.exec(str);

console.log(res[0]);

但你不能将它们匹配在一起,你想要匹配它分开

第二个问题即使是全局标志也是exec() 将输出 首次出现

var str = "Text sample [79zd915j][fxC1bPYW]xxx[asd12233]";
var regex = /(\[[\w\d]{8}\])/g;
var res = regex.exec(str);

console.log(res[0]);

因此,在这种情况下,请使用match()而不使用+并使用全局标记:

var str = "Text sample [79zd915j][fxC1bPYW]xxx[asd12233]";
var regex = /(\[[\w\d]{8}\])/g;
var res = str.match(regex);

console.log(res);

有关regular expression的更多信息。

答案 2 :(得分:1)

TL; DR→使用String.match()代替RegExp.exec()

您的模式/(\[[\w\d]{8}\])+/可以先简化,因为预定义的\w[A-Za-z0-9_]且已包含\d中的所有内容 - 因此我们简化为{{1} }}

您对/(\[\w{8)\])+/的使用意味着匹配一个或多个,所以这意味着匹配+次数,并返回那个,这就是为什么你得到[12345678]是您的第一个结果。

"[79bl9F5j][fKCebPYW][asd12233]"方法返回一个数组,其中包含整个匹配项.exec(),后跟后续数组元素中的每个捕获组。有关执行人员,请参阅the MDN doc

因此,您的第二个数组元素是捕获的组,而不是重复匹配。

您想要全局匹配,因为您要查找{em>所有次result[0]次出现,请删除[12345678]并添加+ } switch,现在提供g

的正则表达式

让我们将其分配给var,这样我们就不必重新输入它了:
/(\[\w{8)\])/g

> var re = /(\[\w{8)\])/g;在您运行时为您提供第一个匹配:

.exec()

但是通过全局匹配,您可以再次(再次)运行它

> re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]");
["[79bl9F5j]", "[79bl9F5j]"]

请看这次它返回第二个匹配。但它已经两次返回......这是因为捕获组。让我们放弃那部分并重新定义我们的重新运行.exec ...

> re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]");
["[fKCebPYW]", "[fKCebPYW]"]

因此,您可以通过在循环中运行> var re = /\[\w{8}\]/g; undefined > re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]"); ["[79bl9F5j]"] > re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]"); ["[fKCebPYW]"] > re.exec("Text sample [79bl9F5j][fKCebPYW][asd12233]"); ["[asd12233]"] 来获取所有匹配项,在同一字符串上重复使用正则表达式,因为regexp对象会记住上下文。

它比这更容易 - 因为您可以String.match(regexp)而不是使用.exec()返回"包含整个匹配结果的数组..."

RegExp.exec()