web-dev-qa-db-ja.com

Notepad ++正規表現グループのキャプチャ

私はそのようなtxtファイルを持っています:

ххх.prontube.ru
salo.ru
bbb.antichat.ru
yyy.ru
xx.bb.prontube.ru
zzz.com
srfsf.jwbefw.com.ua

そのような正規表現を持つすべてのサブドメインを削除しようとしています:

Find:    .+\.((.*?)\.(ru|ua|com\.ua|com|net|info))$
Replace with: \1

受信:

prontube.ru
salo.ru
antichat.ru
yyy.ru
prontube.ru
zzz.com
com.ua

最後の行がcom.uaではなくjwbefw.com.uaになるのはなぜですか?

47
pnslg

これは見回すことなく動作します:

検索:[a-zA-Z0-9-.]+\.([a-zA-Z0-9-]+)\.([a-zA-Z0-9-]+)$置換:_\1\.\2_

少なくとも2つのピリオドと、最後の2つのピリオドに続く文字、数字、ダッシュのみを含むものを見つけます。その後、最後の2つの部分に置き換えます。私の意見では、より直感的です。

その先頭のxxxで面白いことが起こっています。プレーンASCIIのようには見えません。この質問のために、それはこのサイトで面白いものであり、実際のデータを代表するものではないと仮定します。

間違っている

興味深いことに、私は以前、多くの賛成票を集めた間違った答えをここに持っていました。だから私はそれを保存すべきだと思う:

検索:[a-zA-Z0-9-]+\.([a-zA-Z0-9-]+)\.(.+)$置換:_\1\.\2_

少なくとも2つのピリオドが含まれるホスト名を検出し、最初のドット以降のすべてに置き換えます。

48
jpmc26

.+部分は可能な限り一致しています。代わりに.+?を使用してみてください。すると、可能な限りキャプチャが少なくなり、com.uaオプションが一致します。

9
_.+?\.([\w-]*?\.(?:ru|ua|com\.ua|com|net|info))$
_

この回答では、元の質問で調べていた特定のドメイン名が引き続き使用されます。一部のTLD(トップレベルドメイン)にはピリオドがあり、理論的には複数のサブドメインを含むリストを持つことができるため、データセットで機能する場合、正規表現でTLDをホワイトリストに登録することをお勧めします。現在の両方の回答(2013年以降)は、「xx.bb.prontube.ru」と「srfsf.jwbefw.com.ua」の違いを正しく処理しません。

以下に、このpsnigの元の正規表現が意図したとおりに機能しない理由を簡単に説明します。
_+_は貪欲です。 _.+_は、行の最後ですべてをキャプチャして、すべてをキャプチャし、ここから一致するものを探して後方(左)に処理します。

_(ru|ua|com\.ua|com|net|info)_

srfsf.jwbefw.com.uaを使用すると、正規表現エンジンは最初にaとの一致に失敗し、次にトークンを1つ左に移動して「ua」を確認します、正規表現(2番目のオプション)からのuaは一致します。

「.ua」がその要件を満たしたため、エンジンは「com.ua」を探し続けません。

Niet the Dark Absolの答えは正規表現に「怠laz」であることを告げています
_.+?_は、任意の文字(少なくとも1つ)と一致し、正規表現の次の部分を見つけようとします。それが失敗した場合、トークンを進め、_.+_をもう1文字一致させ、残りの正規表現を再度評価します。
。+?最終的に次を消費します:srfsf.jwbefw期間に一致する前に、そしてcom.uaに一致します。

ただし、_?_の実装も問題を引き起こします。

疑問符を追加すると、最初に。+が遅延しますが、group1はprontube.rではなくbb.prontube.rに一致します

これは、bbの後の最初のピリオドが一致し、次にグループ1の_(.*?)_がbb.prontubeと一致するためです。 \.(ru|ua|com\.ua|com|net|info))$が一致する前。r

これを避けるには、3番目のグループを_(.*?)_から_([\w-]*?)_に変更して、文字と数字のみ、またはダッシュのみをキャプチャしないようにします。

結果の正規表現:
.+?\.(([\w-])*?\.(ru|ua|com\.ua|com|net|info))$

最初のグループ以外のグループをキャプチャする必要はないことに注意してください。 ?:を追加すると、TLDオプションがキャプチャされなくなります。

最後の変更:
.+?\.([\w-]*?\.(?:ru|ua|com\.ua|com|net|info))$

1
davidlc