JavaScript正则expression式迭代器来提取组
假设我们有以下文字:“1 a,2 b,3 c,4 d”和下面的expression式:/ \ d(\ w)/ g
我们要做的就是提取正则expression式所表示的a,b,c,d。
不幸的是,“1 a,2 b,3 c,4 d”.match(/ \ d(\ w)/ g)将会产生一个数组:1 a,2 b,3 c,4 d和RegExp。来自上一场比赛的组,即RegExp。$ 1 =='d'。
我怎么能遍历这个正则expression式,以便我可以提取组以及…我正在寻找一个解决scheme,也是有效的内存,即某种迭代器对象
编辑:它需要是通用的。 我只是在这里提供一个简单的例子。 一个解决scheme是循环数组,并重新申请每个项目的正则expression式没有全局标志,但我觉得这个解决scheme有点愚蠢,虽然它似乎是唯一的方法来做到这一点。
var myregexp = /\d (\w)/g; var match = myregexp.exec(subject); while (match != null) { // matched text: match[0] // match start: match.index // capturing group n: match[n] match = myregexp.exec(subject); }
(无耻地从RegexBuddy采取)
更简单(虽然可能效率更低)的解决scheme是使用String.prototype.replace 。 replace是独一无二的,因为它隐式遍历所有的匹配并为每个匹配执行一个函数 。 当然,您可以使用该函数来实际replace文本,但是尽pipe函数名称并非真正需要:
"1 a,2 b,3 c,4 d".replace(/\d (\w)/g, function(complete_match, matched_letter) { console.log(matched_letter); });
这将logginga
, b
, c
,然后d
到控制台。 (它也会碰巧返回"undefined,undefined,undefined,undefined"
,但是我们并不关心这个。)
更一般地说, 用以下参数调用要replace的函数参数 :
function(match, p1, p2, [...], offset, string)
-
match
是匹配的子string。 - 如果有的话,
p1
等是匹配的被捕获的组。 这些组按照它们对应的左括号顺序排列(即最左边第一个,最外面第一个)。 如果组匹配多个子string(即在(.)+
场景中),则只捕获最后一个(最右边的)子string。 -
offset
是此匹配的原始string中的索引 -
string
是调用replace
的string。
手动迭代可能更有效率,但是这种方法并不慢,而且更短,并且(IMHO)更易于阅读; 我倾向于通过手动循环使用这种模式。
这将工作:
"1 a,2 b,3 c,4 d".match(/\w(?:,|$)/g).join(' '); // => "a, b, c, d"
如果您需要迭代:
var r = /\d (\w)/g, s = "1 a,2 b,3 c,4 d", m; while ( m = r.exec(s) ) { // `m` is your match, `m[1]` is the letter }