Javascript Regex exec 只返回第一个匹配项
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5283071/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Regex exec only returning first match
提问by poke
I am trying to implement the following regex search found on golfscript syntax page.
我正在尝试实现在Golfscript 语法页面上找到的以下正则表达式搜索。
var ptrn = /[a-zA-Z_][a-zA-Z0-9_]*|'(?:\.|[^'])*'?|"(?:\.|[^"])*"?|-?[0-9]+|#[^\n\r]*|./mg;
input = ptrn.exec(input);
Input is only ever the first match of the regexp. for example:
"hello" "world"
should return ["hello", "world"]
but it only returns ["hello"]
.
输入只是正则表达式的第一个匹配项。例如:
"hello" "world"
应该返回["hello", "world"]
但它只返回["hello"]
.
回答by poke
RegExp.execis only able to return a single match result at once.
RegExp.exec 一次只能返回一个匹配结果。
In order to retrieve multiple matches you need to run exec
on the expression object multiple times. For example, using a simple while loop:
为了检索多个匹配项,您需要exec
多次在表达式对象上运行。例如,使用一个简单的 while 循环:
var ptrn = /[a-zA-Z_][a-zA-Z0-9_]*|'(?:\.|[^'])*'?|"(?:\.|[^"])*"?|-?[0-9]+|#[^\n\r]*|./mg;
var match;
while ((match = ptrn.exec(input)) != null) {
console.log(match);
}
This will log all matches to the console.
这会将所有匹配记录到控制台。
Note that in order to make this work, you need to make sure that the regular expression has the g
(global) flag. This flag makes sure that after certain methods are executed on the expression, the lastIndex
propertyis updated, so further calls will start afterthe previous result.
请注意,为了完成这项工作,您需要确保正则表达式具有g
(全局)标志。此标志确保在表达式上执行某些方法后,更新lastIndex
属性,因此将在上一个结果之后开始进一步调用。
回答by Eadel
It is possible to call match
method on the string in order to retrieve the whole collection of matches:
可以match
在字符串上调用方法以检索整个匹配集合:
var ptrn = /[a-zA-Z_][a-zA-Z0-9_]*|'(?:\.|[^'])*'?|"(?:\.|[^"])*"?|-?[0-9]+|#[^\n\r]*|./mg;
var results = "hello world".match(ptrn);
results
are (according to the regular expression):
results
是(根据正则表达式):
["hello", " ", "world"]
回答by Little Alien
I did not get what is meant by "hello" "world"
in your question, is it user input or regex but I was told that RegExp object has a state -- its lastIndex
position that it starts the search from. It does not return all the results at once. It brings only the first match and you need to resume .exec
to get the rest of results starting from lastIndex position:
我不明白"hello" "world"
你的问题是什么意思,它是用户输入还是正则表达式,但我被告知 RegExp 对象有一个状态——lastIndex
它开始搜索的位置。它不会一次返回所有结果。它只带来第一场比赛,您需要继续.exec
获得从 lastIndex 位置开始的其余结果:
const re1 = /^\s*(\w+)/mg; // find all first words in every line
const text1 = "capture discard\n me but_not_me" // two lines of text
for (let match; (match = re1.exec(text1)) !== null;)
console.log(match, "next search at", re1.lastIndex);
prints
印刷
["capture", "capture"] "next search at" 7
[" me", "me"] "next search at" 19
The functional JS6 way to build iterator for your results is here
为您的结果构建迭代器的功能性 JS6 方法在这里
RegExp.prototype.execAllGen = function*(input) {
for (let match; (match = this.exec(input)) !== null;)
yield match;
} ; RegExp.prototype.execAll = function(input) {
return [...this.execAllGen(input)]}
Please also note how, unlike poke, much more nicely I used match
variable enclosed in the for
-loop.
另请注意,与poke不同,我如何更好地使用-loop 中match
包含的变量for
。
Now, you can capture your matches easily, in one line
现在,您可以在一行中轻松捕获匹配项
const matches = re1.execAll(text1)
log("captured strings:", matches.map(m=>m[1]))
log(matches.map(m=> [m[1],m.index]))
for (const match of matches) log(match[1], "found at",match.index)
which prints
哪个打印
"captured strings:" ["capture", "me"]
[["capture", 0], ["me", 16]]
"capture" "found at" 0
"me" "found at" 16