Perbedaan antara '.' , '?' dan '*' dalam ekspresi reguler?

21

Bisakah saya mendapatkan contoh tentang bagaimana ketiga elemen ini (apakah ini disebut karakter meta?) Berbeda?

Saya tahu itu *berarti semua atau tidak sama sekali, tetapi saya tidak yakin apakah itu cara yang tepat untuk memikirkannya. Di sisi lain .dan ?tampak sama. Mereka cocok dengan satu karakter, kan?

posixKing
sumber
@Cyrus atau bahkan lebih baik: Dokumentasi StackOverflow Regex .
Thomas Ayoub

Jawaban:

16

Diambil langsung dari Wikipedia :

? Tanda tanya menunjukkan nol atau satu kemunculan elemen sebelumnya. Misalnya, warna cocok dengan "warna" dan "warna".

*Tanda bintang menunjukkan nol atau lebih kemunculan elemen sebelumnya. Misalnya, ab * c cocok dengan "ac", "abc", "abbc", "abbbc", dan sebagainya.

Perbedaan besar adalah bahwa tanda bintang cocok dengan nol atau lebih kejadian, sedangkan tanda tanya cocok dengan nol atau satu kejadian. Bandingkan dua contoh ini:

$ printf "colour\ncolor\ncolouur\n" | egrep 'colou?r'                          
colour
color
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou*r'                          
colour
color
colouur

Karena dalam colouurhuruf u (elemen sebelumnya sebelum kualifikasi ?) terjadi lebih dari satu kali, itu tidak cocok dengan ?, tetapi cocok dengan*

Contoh serupa:

$ printf "error\neror\ner\n" | egrep 'er?or'                                   
eror
$ printf "error\neror\ner\n" | egrep 'er*or'                                   
error
eror

Dari halaman wikipedia yang sama:

Cocok dengan karakter tunggal mana pun (banyak aplikasi mengecualikan baris baru, dan karakter mana yang dianggap baris baru adalah rasa, pengkodean karakter, dan khusus platform, tetapi aman untuk mengasumsikan bahwa karakter umpan baris disertakan). Dalam ekspresi kurung POSIX, karakter titik cocok dengan titik literal. Misalnya, ac cocok dengan "abc", dll., Tetapi [ac] hanya cocok dengan "a", ".", Atau "c".

Dalam contoh kita,

$ printf "colour\ncolor\ncolouur\n" | egrep 'colo.r'                           
colour
$ printf "colour\ncolor\ncolouur\n" | egrep 'colou.r'                          
colouur

Cukup tepat, yang terakhir berbunyi sebagai match any line that has "colou", plus any character, plus letter "r"

Kesimpulan

Anda telah bertanya: "Saya tahu bahwa '*' berarti semua atau tidak sama sekali, tetapi saya tidak yakin apakah itu cara yang tepat untuk memikirkannya. Di sisi lain '.' & '?' tampak sama. " Seperti yang Anda lihat, titik dan tanda bintang tidak persis sama. Titik beroperasi pada karakter apa pun yang mungkin menempati posisi tertentu, sementara tanda tanya beroperasi pada elemen sebelumnya.

Sergiy Kolodyazhnyy
sumber
32

Anda mungkin membingungkan ekspresi reguler dengan gumpalan shell

Dalam sintaks ekspresi reguler .merupakan salah satu karakter (biasanya tidak termasuk karakter baris baru), sedangkan *adalah quantifier berarti nol atau lebih atom regex sebelumnya (karakter atau kelompok). ?adalah quantifier yang berarti nol atau satu contoh dari atom sebelumnya, atau (dalam varian regex yang mendukungnya) pengubah yang mengatur perilaku quantifier menjadi non-serakah.

Dalam gumpalan shell, ?mewakili karakter tunggal (seperti regex .) sementara *mewakili urutan karakter nol atau lebih (setara dengan regex .*).

Beberapa referensi yang mungkin bermanfaat bagi Anda adalah http://www.regular-expressions.info/quickstart.html dan http://mywiki.wooledge.org/glob

Steeldriver
sumber
6

Catatan: Examples provided are in Python.Meskipun konsepnya tetap sama.

'.'adalah simbol yang cocok yang cocok dengan karakter apa pun kecuali karakter baris baru (ini juga dapat diganti dengan re.DOTALLargumen dengan Python). Karenanya ia juga disebut sebagai Wildcard .

'*'adalah quantifier (mendefinisikan seberapa sering suatu elemen dapat terjadi). Adalah kependekan dari {0,} .

Ini berarti “cocok dengan nol atau lebih” - grup yang mendahului bintang dapat muncul beberapa kali dalam teks. Itu bisa sepenuhnya tidak ada atau diulang berulang kali.

'?'juga merupakan penjumlah . Adalah kependekan dari {0,1} .

Ini berarti "Cocokkan nol atau salah satu grup sebelum tanda tanya ini." Itu juga dapat diartikan sebagai bagian sebelum tanda tanya adalah opsional .

misalnya:

pattern = re.compile(r'(\d{2}-)?\d{10}')
mobile1 = pattern.search('My number is 91-9999988888')
mobile1.group()
Output: '91-9999988888'

mobile2 = pattern.search('My number is 9999988888')
mobile2.group()
Output: '9999988888'

Dalam contoh di atas '?' menunjukkan bahwa dua digit sebelum itu adalah opsional. Mereka mungkin tidak terjadi atau terjadi paling banyak sekali.

Perbedaan antara '.' dan '?':

'.'cocok / menerima / memverifikasi karakter tunggal untuk tempat yang dipegangnya dalam ekspresi reguler.

misalnya:

pattern = re.compile(r'.ot')
pattern.findall('dot will identify both hot and got.')
Output: ['dot', 'hot', 'got']

'?'cocok / memverifikasi nol atau kemunculan tunggal grup sebelumnya .

Lihat contoh Nomor ponsel.

Sama halnya dengan '*'. Ini akan memeriksa nol atau lebih kejadian grup sebelumnya .

Kombinasi:

'.*': Menerima sebanyak mungkin urutan yang tersedia. Pendekatan serakah .

'.*?'Menerima urutan dan berhenti yang cocok pertama. Pendekatan Non-Serakah

Untuk info lebih lanjut, pertimbangkan membaca dua pertanyaan berikut ...

Dhaval Simaria
sumber