Saya punya file txt:
ххх.prontube.ru
salo.ru
bbb.antichat.ru
yyy.ru
xx.bb.prontube.ru
zzz.com
srfsf.jwbefw.com.ua
Mencoba untuk menghapus semua subdomain dengan regex:
Find: .+\.((.*?)\.(ru|ua|com\.ua|com|net|info))$
Replace with: \1
Menerima:
prontube.ru
salo.ru
antichat.ru
yyy.ru
prontube.ru
zzz.com
com.ua
Mengapa baris terakhir menjadi com.ua
bukannya jwbefw.com.ua
?
Ini bekerja tanpa terlihat sekitar:
Cari: [a-zA-Z0-9-.]+\.([a-zA-Z0-9-]+)\.([a-zA-Z0-9-]+)$
Ganti: \1\.\2
Ia menemukan sesuatu dengan setidaknya 2 periode dan hanya huruf, angka, dan tanda hubung berikut dua periode, kemudian menggantikannya dengan 2 bagian terakhir. Lebih intuitif, menurut pendapat saya.
Ada's sesuatu yang lucu terjadi dengan yang terkemuka xxx
. Itu doesn't muncul untuk menjadi ASCII biasa. Demi pertanyaan ini, saya'm akan berasumsi bahwa's hanya sesuatu yang lucu dengan situs ini dan tidak mewakili data anda yang sebenarnya.
Menariknya, sebelumnya saya punya jawaban yang salah di sini yang mengumpulkan banyak upvotes. Jadi saya pikir saya harus melestarikannya:
Cari: [a-zA-Z0-9-]+\.([a-zA-Z0-9-]+)\.(.+)$
Ganti: \1\.\2
Ia hanya menemukan sebuah nama host dengan setidaknya 2 periode di dalamnya, kemudian menggantikannya dengan segala sesuatu setelah titik pertama.
.+?\.([\w-]*?\.(?:ru|ua|com\.ua|com|net|info))$
Jawaban ini masih menggunakan nama domain tertentu yang asli pertanyaannya adalah melihat. Karena beberapa TLD (top level domain) memiliki periode di dalamnya, dan anda bisa secara teoritis memiliki daftar termasuk beberapa subdomain, daftar putih TLD di regex adalah ide yang baik jika bekerja dengan data set. Saat ini jawaban (2013) tidak akan menangani perbedaan antara "xx.bb.prontube.ru" dan "srfsf.jwbefw.com.ua" benar.
Berikut ini adalah penjelasan singkat tentang mengapa ini psnig's asli regex isn't bekerja seperti yang dimaksudkan:
The +
adalah serakah.
.+
akan zip semua jalan ke kanan di akhir baris menangkap segala sesuatu,
kemudian bekerja dengan cara mundur (ke kiri) mencari kecocokan dari sini:
(ru|ua|com\.ua|com|net|info)
Dengan srfsf.jwbefw.com.ua regex mesin pertama akan gagal untuk mencocokkan a
,
kemudian akan memindahkan token satu tempat ke kiri untuk melihat "ua"
Pada saat itu, ua
dari regex (pilihan kedua) adalah pertandingan.
Mesin tidak akan terus mencari untuk menemukan "com.ua" karena ".ua" terpenuhi kebutuhan tersebut.
Niet Gelap Ku's jawaban menceritakan regex untuk menjadi "malas"
.+?
akan cocok dengan karakter apapun (setidaknya satu) dan kemudian mencoba untuk menemukan bagian berikutnya dari regex. Jika gagal, itu akan memajukan token, .+
pencocokan satu lagi karakter dan kemudian mengevaluasi sisa regex lagi.
Tersebut .+? pada akhirnya akan mengkonsumsi: srfsf.jwbefw sebelum pencocokan periode, dan kemudian mencocokkan com.ua.
Tapi terimplementasikan ?
juga menciptakan masalah.
Menambahkan tanda tanya membuat yang pertama .+ malas, tapi kemudian menyebabkan group1 untuk mencocokkan bb.prontube.ru bukan prontube.ru
Hal ini karena periode pertama setelah bb akan cocok, kemudian di dalam group 1 (.*?)
akan mencocokkan bb.prontube. sebelum \.(ru|ua|com\.ua|com|net|info))$
sesuai .ru
Untuk menghindari hal ini, perubahan yang kelompok ketiga dari (.*?)
ke ([\w-]*?)
sehingga tidak't capture . hanya huruf dan angka, atau tanda hubung.
sehingga regex: *`.+?.(([\w-])?.(ru|ua|com.ua|com|net|info))$`**
Perhatikan bahwa anda don't perlu untuk menangkap setiap kelompok yang lain daripada yang pertama. Menambahkan ?: membuat TLD pilihan non-menangkap.
perubahan terakhir: *`.+?.([\w-]?.(?:ru|ua|com.ua|com|net|info))$`**