正規表現の非キャプチャグループとは何ですか?

1881
never_had_a_name 2010-08-19 03:17.

非キャプチャグループ、つまり(?:)正規表現でどのように使用され、それらは何に適していますか?

15 answers

2462
Ricardo Nolde 2010-08-19 05:39.

これを例を挙げて説明してみましょう。

次のテキストを検討してください。

http://stackoverflow.com/
https://stackoverflow.com/questions/tagged/regex

さて、下の正規表現をその上に適用すると...

(https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?

...次の結果が得られます。

Match "http://stackoverflow.com/"
     Group 1: "http"
     Group 2: "stackoverflow.com"
     Group 3: "/"

Match "https://stackoverflow.com/questions/tagged/regex"
     Group 1: "https"
     Group 2: "stackoverflow.com"
     Group 3: "/questions/tagged/regex"

ただし、プロトコルは気にしません。URLのホストとパスだけが必要です。そこで、非キャプチャグループを含むように正規表現を変更します(?:)

(?:https?|ftp)://([^/\r\n]+)(/[^\r\n]*)?

今、私の結果は次のようになります:

Match "http://stackoverflow.com/"
     Group 1: "stackoverflow.com"
     Group 2: "/"

Match "https://stackoverflow.com/questions/tagged/regex"
     Group 1: "stackoverflow.com"
     Group 2: "/questions/tagged/regex"

見る?最初のグループはキャプチャされていません。パーサーはそれを使用してテキストを照合しますが、後で無視して最終結果を出します。


編集:

ご要望に応じて、グループについても説明させていただきます。

ええと、グループは多くの目的を果たします。これらは、より大きな一致(名前を付けることもできます)から正確な情報を抽出するのに役立ち、以前に一致したグループを再一致させ、置換に使用できます。いくつか例を見てみましょう。

ある種のXMLまたはHTMLがあると想像してください(正規表現は仕事に最適なツールではないかもしれませんが、例としては便利です)。タグを解析したいので、次のようにすることができます(理解しやすいようにスペースを追加しました)。

   \<(?<TAG>.+?)\> [^<]*? \</\k<TAG>\>
or
   \<(.+?)\> [^<]*? \</\1\>

最初の正規表現には名前付きグループ(TAG)があり、2番目の正規表現は共通のグループを使用します。どちらの正規表現も同じことを行います。最初のグループの値(タグの名前)を使用して、終了タグと一致させます。違いは、最初の名前は値と一致する名前を使用し、2番目の名前はグループインデックス(1から始まる)を使用することです。

今、いくつかの置換を試してみましょう。次のテキストを検討してください。

Lorem ipsum dolor sit amet consectetuer feugiat fames malesuada pretium egestas.

それでは、このばかげた正規表現を使用してみましょう。

\b(\S)(\S)(\S)(\S*)\b

この正規表現は、少なくとも3文字の単語と一致し、グループを使用して最初の3文字を区切ります。結果は次のとおりです。

Match "Lorem"
     Group 1: "L"
     Group 2: "o"
     Group 3: "r"
     Group 4: "em"
Match "ipsum"
     Group 1: "i"
     Group 2: "p"
     Group 3: "s"
     Group 4: "um"
...

Match "consectetuer"
     Group 1: "c"
     Group 2: "o"
     Group 3: "n"
     Group 4: "sectetuer"
...

したがって、置換文字列を適用すると、次のようになります。

$1_$3$2_$4

...その上で、最初のグループを使用し、アンダースコアを追加し、3番目のグループを使用し、次に2番目のグループを使用し、別のアンダースコアを追加し、次に4番目のグループを追加しようとしています。結果の文字列は次のようになります。

L_ro_em i_sp_um d_lo_or s_ti_ a_em_t c_no_sectetuer f_ue_giat f_ma_es m_la_esuada p_er_tium e_eg_stas.

を使用して、名前付きグループを置換に使用することもできます${name}

正規表現をいじるには、お勧めします http://regex101.com/、正規表現がどのように機能するかについての詳細を提供します。また、いくつかの正規表現エンジンから選択することもできます。

190
Bill the Lizard 2010-08-19 03:24.

キャプチャグループを使用して、式を整理および解析できます。キャプチャしないグループには最初の利点がありますが、2番目の利点はありません。たとえば、キャプチャしないグループはオプションであると言えます。

数値テキストに一致させたいが、一部の数値は1番目、2番目、3番目、4番目などと書くことができます...数値部分をキャプチャしたいが、(オプションの)サフィックスをキャプチャしたくない場合は、キャプチャしないグループを使用できます。

([0-9]+)(?:st|nd|rd|th)?

これは、1、2、3 ...または1st、2nd、3rd、...の形式の数値と一致しますが、数値部分のみをキャプチャします。

111
RC. 2010-08-19 03:22.

?: 式をグループ化したいが、文字列の一致/キャプチャされた部分として保存したくない場合に使用されます。

例としては、IPアドレスに一致するものがあります。

/(?:\d{1,3}\.){3}\d{1,3}/

最初の3オクテットを保存する必要はありませんが、(?:...)グループ化により、一致をキャプチャして保存するオーバーヘッドを発生させることなく、正規表現を短縮できることに注意してください。

39
sepp2k 2010-08-19 03:23.

これにより、グループが非キャプチャになります。つまり、そのグループに一致する部分文字列は、キャプチャのリストに含まれません。違いを説明するためのルビーの例:

"abc".match(/(.)(.)./).captures #=> ["a","b"]
"abc".match(/(?:.)(.)./).captures #=> ["b"]
30
user2369060 2016-02-04 22:07.

歴史的な動機:

非キャプチャグループの存在は、括弧を使用して説明できます。

(a|b)cとを考えてみましょう。a|bc連結が優先されるため|、これらの式は2つの異なる言語({ac, bc}および{a, bc}それぞれ)を表します。

ただし、括弧は一致するグループとしても使用されます(他の回答で説明されているように...)。

括弧を付けたいが部分式をキャプチャしたくない場合は、NON-CAPTURINGGROUPSを使用します。例では、(?:a|b)c

28
shekhar gehlot 2017-01-20 01:36.

例を挙げてこれを試してみましょう。

正規表現コード: (?:animal)(?:=)(\w+)(,)\1\2

検索文字列:

ライン1 - animal=cat,dog,cat,tiger,dog

2行目 - animal=cat,cat,dog,dog,tiger

3行目- animal=dog,dog,cat,cat,tiger

(?:animal) ->捕獲されていないグループ1

(?:=)->キャプチャされていないグループ2

(\w+)->キャプチャされたグループ1

(,)->キャプチャされたグループ2

\1 ->キャプチャされたグループ1の結果。つまり、1行目は猫、2行目は猫、3行目は犬です。

\2 ->キャプチャされたグループ2の結果、つまりコンマ(、)

したがって、このコードでは、与えて\1\2キャプチャされたグループ1と2の結果をそれぞれコードの後半で呼び出すか繰り返します。

コードの順序に従って、(?:animal)グループ1である(?:=)必要があり、グループ2である必要があり、続行します。

しかし、与える?:ことによって、マッチグループを非キャプチャにします(これは、一致したグループではカウントされないため、グループ化番号は、キャプチャされていないグループではなく、最初にキャプチャされたグループから始まります)。その結果、マッチグループの結果が繰り返されます。(?:animal)後でコードで呼び出すことはできません。

これが非キャプチャグループの使用を説明することを願っています。

15
Bob Fincheimer 2010-08-19 03:22.

グループのキャプチャあなたが一致する正規表現中に、後に使用することができますまたはあなたが正規表現の交換部品でそれらを使用することができます。非キャプチャグループを作成すると、これらの理由のいずれかのためにそのグループの使用が免除されます。

キャプチャしないグループは、さまざまなものをキャプチャしようとしていて、キャプチャしたくないグループがいくつかある場合に最適です。

それが彼らが存在する理由のほとんどです。あなたがグループについて学んでいる間、アトミックグループについて学んでください、彼らはたくさんします!ルックアラウンドグループもありますが、それらはもう少し複雑であまり使用されていません。

後で正規表現(後方参照)で使用する例:

<([A-Z][A-Z0-9]*)\b[^>]*>.*?</\1> [xmlタグを検索します(nsサポートなし)]

([A-Z][A-Z0-9]*) はキャプチャグループです(この場合はタグ名です)

後の正規表現では\1、最初のグループ(([A-Z][A-Z0-9]*)グループ)にあったのと同じテキストのみに一致します(この場合は終了タグに一致します)。

11
Aaron S 2018-05-11 19:27.

tl; dr非キャプチャグループは、名前が示すように、一致に含めたくない正規表現の部分であり?:、グループを非キャプチャとして定義する方法です。

あなたがメールアドレスを持っているとしましょう[email protected]。次の正規表現は、id部分と@ example.com部分の2つのグループを作成します。(\p{Alpha}*[a-z])(@example.com)。簡単にするために、@文字を含むドメイン名全体を抽出しています。

ここで、アドレスのid部分のみが必要であるとしましょう。実行したいの()は、正規表現で囲まれた一致結果の最初のグループを取得することです。これを行う方法は、非キャプチャグループ構文を使用すること?:です。したがって、正規表現(\p{Alpha}*[a-z])(?:@example.com)は電子メールのID部分のみを返します。

9
Gaurav 2016-03-01 23:43.

私はJavaScript開発者であり、JavaScriptに関するその重要性を説明しようと思います。

cat is animal猫と動物を一致させたいときに一致させたいシナリオを考えてみましょうis。両方の間にある必要があります。

 // this will ignore "is" as that's is what we want
"cat is animal".match(/(cat)(?: is )(animal)/) ;
result ["cat is animal", "cat", "animal"]

 // using lookahead pattern it will match only "cat" we can
 // use lookahead but the problem is we can not give anything
 // at the back of lookahead pattern
"cat is animal".match(/cat(?= is animal)/) ;
result ["cat"]

 //so I gave another grouping parenthesis for animal
 // in lookahead pattern to match animal as well
"cat is animal".match(/(cat)(?= is (animal))/) ;
result ["cat", "cat", "animal"]

 // we got extra cat in above example so removing another grouping
"cat is animal".match(/cat(?= is (animal))/) ;
result ["cat", "animal"]
8
Scott Anderson 2018-01-02 15:04.

私はこれを言うためにトップの答えにコメントすることはできません:私はトップの答えにのみ暗示されている明示的なポイントを追加したいと思います:

非キャプチャグループ(?...)は、元の完全一致から文字を削除、プログラマに視覚的に正規表現を再編成するだけです。

定義された無関係な文字なしで正規表現の特定の部分にアクセスするには、常に使用する必要があります .group(<index>)

7
Jack Peng 2014-03-09 07:33.

複雑な正規表現では、多数のグループを使用したい場合があります。その一部は繰り返しマッチング用にあり、一部は逆参照を提供するためにあります。デフォルトでは、各グループに一致するテキストが後方参照配列にロードされます。多数のグループがあり、後方参照配列からそれらの一部を参照できる必要がある場合は、このデフォルトの動作をオーバーライドして、特定のグループが繰り返し処理のためだけに存在し、キャプチャして保存する必要がないことを正規表現に伝えることができます。後方参照配列内。

6
RBT 2017-07-15 17:13.

私が遭遇した興味深い点の1つは、非キャプチャグループ内にキャプチャグループを含めることができるという事実です。一致するWebURLについては、以下の正規表現を参照してください。

var parse_url_regex = /^(?:([A-Za-z]+):)(\/{0,3})([0-9.\-A-Za-z]+)(?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;

入力URL文字列:

var url = "http://www.ora.com:80/goodparts?q#fragment";

私の正規表現の最初のグループは、(?:([A-Za-z]+):)プロトコルスキームとコロン:文字に一致する非キャプチャグループです。つまりhttp:、コードの下で実行しているときに、返された配列の最初のインデックスに文字列が含まれてhttpいることhttpを確認しました。:どちらもキャプチャされていないグループ内にあるため、報告されません。

console.debug(parse_url_regex.exec(url));

最初のグループ(?:([A-Za-z]+):)が非キャプチャグループである場合、なぜhttp出力配列に文字列を返すのかを考えました。

したがって([A-Za-z]+)、非キャプチャグループ内にネストされたグループがあることに気付いた場合。そのネストされたグループ([A-Za-z]+)は、?:それ自体が非キャプチャグループ内のキャプチャグループ(最初はありません)(?:([A-Za-z]+):)です。そのため、テキストはhttp引き続きキャプチャされますが、:非キャプチャグループ内でキャプチャグループ外のコロン文字は出力配列に報告されません。

3
Harini 2017-05-24 03:40.

私はあなたに答えを与えると思います。一致が成功したことを確認せずにキャプチャ変数を使用しないでください。

キャプチャ変数$1などは、一致が成功しない限り無効であり、それらもクリアされません。

#!/usr/bin/perl  
use warnings;
use strict;   
$_ = "bronto saurus burger";
if (/(?:bronto)? saurus (steak|burger)/)
{
    print "Fred wants a  $1"; } else { print "Fred dont wants a $1 $2";
}

上記の例では、ブロントのキャプチャを回避するために$1(?:)が使用されています。

パターンが一致する場合、$1次のグループ化されたパターンとしてキャプチャされます。

したがって、出力は次のようになります。

Fred wants a burger

一致を保存したくない場合に便利です。

2
AmerllicA 2018-05-07 17:50.

Google Chrome devToolsを開き、[コンソール]タブを開きます。次のように入力します。

"Peace".match(/(\w)(\w)(\w)/)

それを実行すると、次のように表示されます。

["Pea", "P", "e", "a", index: 0, input: "Peace", groups: undefined]

JavaScript正規表現エンジンキャプチャ三つのグループ、インデックス1,2,3を持つアイテム。次に、非キャプチャマークを使用して結果を確認します。

"Peace".match(/(?:\w)(\w)(\w)/)

結果は次のとおりです。

["Pea", "e", "a", index: 0, input: "Peace", groups: undefined]

これは、非キャプチャグループが何であるかは明らかです。

2
Naved Ahmad 2019-01-07 22:02.

その非常に単純な、単純な日付の例で理解できます。日付が2019年1月1日または2019年5月2日、あるいはその他の日付として言及されていて、それをdd / mm / yyyy形式に変換したい場合は月の名前は1月または2月であるため、数値部分をキャプチャするために、(オプションの)サフィックスではなく、キャプチャしないグループを使用できます。

したがって、正規表現は次のようになります。

([0-9]+)(?:January|February)?

それと同じくらい簡単です。

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする&nbsp;

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

Westworldの遊び方:Amazonエコーのない迷路

Westworldの遊び方:Amazonエコーのない迷路

Westworldの第2シーズンが終わり、次の1、2年は楽しいがやや混乱するシリーズでモーター機能が凍結するので、次に何をすべきかについて少し迷うかもしれません。ビンジウォッチングする別の番組を見つけますか?さらに多くのファン理論を読み直しますか?お気に入りの1990年代のオルタナティブロックソングの楽しいオールドタイムの​​ピアノカバーを書き始めますか?心配しないでください。長い待ち時間が始まる前に、Westworldのヒットをもう1つ得ることができます。

ジャネールモネイは彼女のプライドで周りをファックしませんでしたBETアワードを見てください

ジャネールモネイは彼女のプライドで周りをファックしませんでしたBETアワードを見てください

2018 BETアワードは、日曜日の夜にロサンゼルスで開催されました。プライド月の真ん中に軽くたたきます。見た目はいたるところに強かったが、ジャネール・モネイのように誰もそれをしなかった。

リットウッドで2000年代と2010年代の車を祝うために2038年に会いましょう

リットウッドで2000年代と2010年代の車を祝うために2038年に会いましょう

他の期間をテーマにした自動車展示会、特に1980年代と90年代の自動車ショーRadwoodの最近の成功に続いて、私は2000年代と2010年代の自動車文化を祝う自動車ショーであるLitwoodを立ち上げることにしました。私は今これについてディブを呼んでいます。

リチャードは堅実なシリコンバレーで彼の会社の将来のためにビットコインを裏返します

リチャードは堅実なシリコンバレーで彼の会社の将来のためにビットコインを裏返します

数週間前のシリコンバレーの第5シーズンのプレミアのレビューで、ショーはその高齢で問題を抱え続けていますが、才能のあるキャストとそのひねくれたユーモアのセンスを備えた頑丈な基盤からまだ機能していると主張しました。そして、シーズンの終わりに近づくにつれて、その点は持ちこたえてきました。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language