この非キャプチャグループにgrepが役に立ちますか?

この非キャプチャグループにgrepが役に立ちますか?

私はGNU / Linuxと正規表現に初めて触れました。最近は正規表現を身につけようとしています。これまではかなりしっかりした基本理解を持っていると思います。今PCREを掘っています。

これは私が使っている練習テキストファイルです:

01234 567890

01111-222111

09876.543210

次のようにして、正常に数字を一致させることができます。

(\d{5})[-.]?\s*?(\d{6})

最初の5桁は省略し、最後の6桁だけに一致するように非キャプチャグループを作成したいと思います。だから私は(?:)キャプチャしないグループを代表し、キャプチャしたくないものを入力したと思います。そうですか?だからそれは

(?:\d{5})[-.]?\s*?(\d{6})

ターミナルでPCREを使用してgrep -Po出力を表示しながら、これを実行しましたが、キャプチャグループが適用されていないかのように、まだ正確に一致する結果が得られました。

どのような指示がありますか?

答え1

-oまたは、オプションを使用すると、キャプチャはgrepが一致の一部と見なす項目には影響しません--only-matching。すべての非キャプチャは、グループが利用可能な逆参照の1つとして計算されるか、置換がオプションのコンテキストで置き換えられないことを意味します。

たとえば、

$ printf 'aba\nabb\nabc\n' | grep -Po '(a)(b)'
ab
ab
ab
$ printf 'aba\nabb\nabc\n' | grep -Po '(a)(b)\1'
aba
$ printf 'aba\nabb\nabc\n' | grep -Po '(?:a)(b)\1'
abb

おそらくこの場合、あなたが探しているもの長さ0の行の後の主張:

printf 'aba\nabb\nabc\n' | grep -Po '(?<=a)b'
b
b
b

それとも\K「左を保ちなさい」という考え

$ printf 'aba\nabb\nabc\n' | grep -Po 'a\Kb'
b
b
b

(後者は可変長マッチングを可能にするので、やや柔軟です)。

例えば

$ grep -Po '\d{5}[-.]?\s*\K\d{6}' file
567890
222111
543210

答え2

使用中の正規表現は一致するには複雑すぎるようです。一つ中間文字は-、a、.または空白にすることができます。なぜ必要ですか[-.]?\s*??次のようになります:a-またはa .(オプション(`?))と一致し、その後にスペースが続きます(まあ、実際には(man pcrepatternから)):デフォルトの \s 文字は、HT(9)、LF(10)、VT(11)、FF(12)、CR(13)、および空白 (32) です。)。まあ、実際には怠惰なモードにはいくつかのスペース(*?)があります。

[ .-]私の考えには、1文字、スペース、ドット、またはダッシュを使用するだけです。この正規表現は次のとおりです。

(\d{5})[-. ](\d{6})

これを試すのに最適な場所(正規表現を学ぶ唯一の実際の方法)は、regex101.comに行って試してみることです。こここの投稿の例を作成しました。詳細情報(PCREでははい)。

あなたが尋ねた代替品目では、私は次のような代替品目を配置したことがわかります。

(one:\1) (two:\2) (three:3)

各行の周囲のテキストではなく、完全一致(正規表現の先頭から最後まで)がその文字列に置き換えられ、合計がキャプチャされた値に\1変換されることがわかります。\21人あたり1人分(...)

(...)最初の非キャプチャを作成したい場合は、次の手順を実行します。一つグループをキャプチャする場合は、代替エントリを次のように変更する必要があります。

(one:1) (two:\1) (three:3)

単一\1。それ以外の場合、交換は失敗します。

行全体を置き換えるには、最初から最後まで行全体と一致するようにします。

^.*(?:\d{5})[-. ](\d{6}).*$

\1最後の数値セットのみを印刷するには、交換を実行してください。

それではgrepについて学びましょう。 Grepを置き換えることはできません。 「多少」役に立ちますが、それに対応するわけではありません\K

grep -Po '^.*\d{5}[-. ]\K\d{6}' file

重要なアイデアは、-o正規表現が一致するすべてのもの、はい、各一致する角かっこではなく完全な正規表現を提供することを目指すことです。

実際の置換(または置換(s///))を使用するには、次のものが必要ですsed(ただしPCREの代わりにBREを使用します)。

$ sed 's/^.*\([0-9]\{5\}\)[-. ]\([0-9]\{6\}\).*$/ \2 \1 /' file
 567890 01234 
 222111 01111 
 543210 09876

これは実際には置き換えであるため、順序の変更(または重複)が許可されます。

答え3

grep最後の6文字の数字の行ブロックを出力するには、次のようにします。

grep -Po "\d{6}$" file

区切り文字を決定するには、次の図形を追加します。

grep -Po "(?<=[-. ])\d{6}$" file

または桁数が不確実な場合

grep -Po "\d+$" file

どちらの場合も、行の末尾に固定して再接続します。

私は最善の計画は一般的に処理する必要がない部分は処理しないことだと思います。すべて学ぶために難しいことをすることの美徳...ただ続ける;D)。

答え4

次のコマンドを使用して目的の出力を取得できますpcregrepLinuxのコマンド。それは拡張される-oオプションを使用すると、選択したキャプチャグループを出力できます。 2番目のセットが欲しいので、次のものを使用できます。 -onumber-o2:

$ pcregrep -o2 '(\d{5})[-.]?\s*?(\d{6})' input
567890
222111
543210

関連情報