58

私はそのような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ですか?

4

4 に答える 4

62

これは見回さずに機能します:

検索:[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 つのピリオドを含むホスト名を見つけて、最初のドットの後のすべてのものに置き換えます。

于 2013-07-01T23:30:25.333 に答える
10

パーツは.+なるべく合わせています。代わりに使用してみてください。.+?可能な限り最小限のものをキャプチャし、com.uaオプションが一致するようにします。

于 2013-07-01T22:14:04.360 に答える
1
.+?\.([\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" を確認します。その時点でua、正規表現から (2 番目のオプション) が一致します。

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

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

しかし、実装は?問題も引き起こします。

疑問符を追加すると、最初の .+ が遅延しますが、その後 group1 がprontube.ruではなくbb.prontube.ruに一致するようになります。

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

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

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

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

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

于 2019-08-21T20:09:10.600 に答える