簡體   English   中英

Javascript RegExp非捕獲組

[英]Javascript RegExp non-capturing groups

我正在編寫一組RegExps,以將CSS選擇器轉換為ID和類的數組。

例如,我希望'#foo#bar'返回['foo','bar']。

我一直在努力實現這一目標

"#foo#bar".match(/((?:#)[a-zA-Z0-9\-_]*)/g)

但當非捕獲前綴?:忽略#字符時,它將返回['#foo','#bar']。

是否有比將每個返回的字符串切片更好的解決方案?

您可以在循環中使用.replace().exec()來構建數組。

使用.replace()

var arr = [];
"#foo#bar".replace(/#([a-zA-Z0-9\-_]*)/g, function(s, g1) {
                                               arr.push(g1);
                                          });

使用.exec()

var arr = [],
    s = "#foo#bar",
    re = /#([a-zA-Z0-9\-_]*)/g,
    item;

while (item = re.exec(s))
    arr.push(item[1]);

它與#foo#bar匹配,因為外部組(#1)正在捕獲。 內部組(#2)不是,但是那可能不是您要檢查的組。

如果您沒有使用全局匹配模式,則立即解決方法是改用(/(?:#)([a-zA-Z0-9\\-_]*)/

在全局匹配模式下,由於match行為不同,因此結果不能僅一行顯示。 僅使用正則表達式(即不使用字符串操作),您需要這樣做:

var re = /(?:#)([a-zA-Z0-9\-_]*)/g;
var matches = [], match;
while (match = re.exec("#foo#bar")) {
    matches.push(match[1]);
}

看到它在行動

我不確定是否可以使用match()來做到這一點,但是可以使用RegExp的exec()方法來做到這一點:

var pattern = new RegExp('#([a-zA-Z0-9\-_]+)', 'g');
var matches, ids = [];

while (matches = pattern.exec('#foo#bar')) {
    ids.push( matches[1] ); // -> 'foo' and then 'bar'
}

不幸的是,Javascript RegExp中沒有后向斷言,否則您可以這樣做:

/(?<=#)[a-zA-Z0-9\-_]*/g

除了將其添加到某些新版本的Javascript中之外,我認為使用split后處理是最好的選擇。

您可以使用否定的超前斷言:

"#foo#bar".match(/(?!#)[a-zA-Z0-9\-_]+/g);  // ["foo", "bar"]

mVChr幾年前提到的回溯斷言已添加到ECMAScript 2018中 這將允許您執行以下操作:

'#foo#bar'.match(/(?<=#)[a-zA-Z0-9\\-_]*/g) (返回["foo", "bar"]

(也可以使用負向后看:使用(?<!#)匹配除#以外的任何字符,而不捕獲它。)

MDN確實記錄到“使用帶全局/ g標志的match()時捕獲組將被忽略” ,並建議使用matchAll() matchAll() isn't available on Edge or Safari iOS, and you still need to skip the complete match (including the #`)。

一個更簡單的解決方案是,如果您知道前導前綴的長度,則將其切掉-在這里, # 1。

 const results = ('#foo#bar'.match(/#\\w+/g) || []).map(s => s.slice(1)); console.log(results); 

[] || ... [] || ...部分是必需的,以防不存在匹配項,否則match返回null,並且null.map將不起作用。

 const results = ('nothing matches'.match(/#\\w+/g) || []).map(s => s.slice(1)); console.log(results); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM