[解決済み] 正規表現における非捕捉グループとは何ですか?
質問
非捕獲グループ、すなわち、どのように。
(?:)
正規表現ではどのように使われ、どのような用途に使われるのですか?
どのように解決するのですか?
例を挙げて説明しましょう。
次のような文章を考えてみましょう。
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"
ほらね。最初のグループは捕捉されていないのです。パーサーはそれを使ってテキストをマッチングしますが、最終結果では後でそれを無視します。
EDITです。
リクエストにお応えして、グループについても説明してみます。
さて、グループには多くの目的があります。大きなマッチから正確な情報を抽出したり(名前をつけることもできます)、前にマッチしたグループと再マッチさせたり、置換に使ったりします。いくつか例を挙げてみましょう。
ある種の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/ には、正規表現がどのように機能するのかについての十分な詳細が記載されており、また、いくつかの正規表現エンジンから選択することができます。
関連
-
[解決済み] アポストロフィの正規表現
-
[解決済み] 正規表現で変数を使うには?
-
[解決済み] 文字列の最後の文字にマッチする正規表現[重複]について
-
[解決済み] 正規表現で「逆マッチ」を行うには?
-
[解決済み] awk で gsub を使ってファイル中の ("./") と (".txt") の文字を検索・置換する方法
-
[解決済み] 単語を含まない行にマッチする正規表現
-
[解決済み] JavaScriptの正規表現でマッチしたグループにアクセスするにはどうすればよいですか?
-
[解決済み] Microsoft Excelで正規表現(Regex)をセル内とループの両方で使用する方法
-
[解決済み] jQueryセレクタの正規表現
-
[解決済み] Sublime Text 2での正規表現検索置換
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] 正規表現でのコロン記号の使用
-
[解決済み] MACアドレスの正規表現とは何ですか?
-
[解決済み] 正規表現におけるスラッシュのエスケープ
-
[解決済み] Regex Last occurrence?
-
[解決済み] Scalaで正規表現を使ったパターンマッチを行うには?
-
[解決済み] Atomで改行文字を置き換えるには?
-
[解決済み] Regex オプション文字にマッチさせる方法
-
[解決済み] Bashスクリプトで文字列が正規表現にマッチするかどうかをチェックする
-
[解決済み] Powershellで完全一致の文字列のみを置換する
-
[解決済み] RegExp マッチする文字列が my で始まらない