11

CSSセレクターをIDとクラスの配列に変換するための一連のRegExpsを作成しています。

たとえば、「#foo#bar」で['foo'、'bar']を返したいとします。

私はこれを達成しようとしてきました

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

ただし、キャプチャしないプレフィックス?:が#文字を無視する必要がある場合は、['#foo'、'#bar']を返します。

返された文字列をそれぞれスライスするよりも良い解決策はありますか?

4

7 に答える 7

12

.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]);
于 2012-06-02T18:29:51.097 に答える
5

一致#foo#bar外側のグループ(#1)がキャプチャしているためです。内側のグループ(#2)はそうではありませんが、おそらくそれはあなたがチェックしているものではありません。

グローバルマッチングモードを使用していなかった場合は、(/(?:#)([a-zA-Z0-9\-_]*)/代わりにすぐに修正する必要があります。

グローバルマッチングモードでは、match動作が異なるため、結果を1行だけにすることはできません。正規表現のみを使用する(つまり、文字列操作を使用しない)場合は、次のようにする必要があります。

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

実際の動作をご覧ください

于 2012-06-02T18:19:40.050 に答える
2

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'
}
于 2012-06-02T18:32:25.050 に答える
1

負の先読みアサーションを使用できます。

"#foo#bar".match(/(?!#)[a-zA-Z0-9\-_]+/g);  // ["foo", "bar"]
于 2012-06-02T18:44:04.037 に答える
1

残念ながら、Javascript RegExpには後読みアサーションはありません。それ以外の場合は、次のようにすることができます。

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

新しいバージョンのJavascriptに追加されることを除けば、split後処理を使用するのが最善の策だと思います。

于 2012-06-02T18:31:16.743 に答える
1

数年前にmVChrによって言及された後読みアサーションがECMAScript2018に追加されました。これにより、次のことが可能になります。

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

(ネガティブルックビハインドも可能です(?<!#)。キャプチャせずに、#以外の任意の文字に一致させるために使用します。)

于 2018-04-19T00:50:55.360 に答える
0

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);

[] || ...一致するものがなかった場合に必要なパーツです。一致しない場合はmatchnullを返し、機能しnull.mapません。

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

于 2019-05-12T21:04:22.017 に答える