Contoh ungkapan biasa Perl. Metacharacter dalam ungkapan biasa. Sintaks ungkapan biasa

Ungkapan biasa Perl

perlre- Ungkapan biasa Perl
Tutorial ini menerangkan sintaks ungkapan biasa dalam Perl. Penerangan tentang cara praktikal menggunakan ungkapan biasa dalam operasi pemadanan corak, serta pelbagai contoh mengenai topik ini, boleh didapati di bahagian m// Dan s/// pada halaman bantuan perlop.

PENERANGAN ungkapan biasa

Operasi pemadanan boleh mempunyai pelbagai pengubah suai, termasuk yang berkaitan dengan tafsiran ungkapan biasa yang digunakan. Ini adalah pengubah suai:

Yang terakhir ini biasanya dipanggil "/x pengubah", walaupun pembatas yang dimaksudkan mungkin bukan garis miring ke hadapan. Malah, mana-mana pengubah suai ini boleh dibina menjadi ungkapan biasa menggunakan binaan baharu (?...) . Lihat di bawah.

Pengubah suai itu sendiri /x memerlukan sedikit lagi perincian. Ia menyebabkan penghurai ungkapan biasa diabaikan aksara ruang putih, tidak terlepas dengan garis miring ke belakang dan bukan sebahagian daripada kelas aksara. Ini boleh digunakan untuk memecahkan ungkapan biasa kepada (sedikit) bahagian yang lebih mudah difahami. Simbol # juga dianggap sebagai metakarakter permulaan ulasan, seperti dalam kod Perl yang lain. Jika digabungkan, ciri ini menjadikan Perl 5 bahasa yang lebih mudah dibaca. Lihat kod contoh untuk mengalih keluar ulasan dalam program C pada halaman manual perlop.

Ungkapan Biasa

Corak yang digunakan dalam padanan corak ialah ungkapan biasa jenis yang digunakan dalam versi 8 perpustakaan regexp. (Malah, fungsi yang sepadan diperolehi (walaupun sangat jauh) daripada pelaksanaan versi 8 Henry Spencer yang tersedia secara percuma.) Untuk butiran lanjut, lihat bahagian "Ungkapan biasa versi 8".

Khususnya, yang berikut metakarakter mempunyai standard, biasa egrep, nilai:

Secara lalai, simbol " ^ " dijamin hanya sepadan dengan permulaan rentetan dan watak " $ " - hanya penghujung baris (atau kedudukan sebelum baris baharu pada penghujung), dan Perl membuat beberapa pengoptimuman berdasarkan andaian bahawa penimbal mengandungi hanya satu baris. Suapan baris terbina dalam tidak akan sepadan dengan aksara meta " ^ "atau" $ ". Walau bagaimanapun, mungkin perlu untuk menganggap penimbal sebagai berbilang baris, supaya " ^ " sepadan dengan kedudukan selepas aksara baris baharu dalam penimbal, dan " $ " - kedudukan sebelum aksara baris baharu. Dengan mengorbankan sedikit peningkatan dalam overhed, ini boleh dilakukan menggunakan pengubah suai /m dalam operator padanan corak. (Program lama untuk ini telah dipasang $* , tetapi amalan ini tidak lagi masuk akal dalam Perl 5.)

Untuk memudahkan penggantian berbilang baris, " . " tidak pernah padan dengan aksara baris baharu melainkan pengubah suai digunakan /s, yang memberitahu Perl untuk merawat penimbal sebagai satu baris - walaupun ia mengandungi berbilang baris. Pengubah suai /s juga membatalkan pemasangan $* , jika kod lama (tidak berjaya) digunakan, tetapkannya dalam modul lain.

Yang berikut diiktiraf pengkuantiti piawai:

(Jika pendakap kerinting berlaku dalam mana-mana konteks lain, ia dianggap sebagai aksara biasa.) Pengubah suai " * " adalah setara {0,} , pengubah suai " + " - {1,} , dan pengubah suai " ? " - {0,1} . n Dan m mesti mempunyai nilai integer tidak melebihi 65536.

Secara lalai, subcorak yang dikira adalah "tamak", i.e. ia akan memadankan seberapa banyak kejadian yang mungkin supaya corak yang lain dapat dipadankan. Semua pengkuantiti piawai adalah "tamak" kerana dipadankan dengan bilangan maksimum kemungkinan kejadian (bermula dari lokasi tertentu). Jika anda ingin memadankan dengan bilangan minimum kemungkinan kejadian, anda mesti menyatakan " selepas pengkuantiti ? ".

Pertimbangkan apa yang berubah bukan maksud pengkuantiti, tetapi "berat", - mereka akan dibandingkan dengan subrentetan terkecil yang mungkin:

Kerana corak dianggap sebagai rentetan petikan dua kali, aksara meta berikut juga akan berfungsi:

\t penjadualan
\n terjemahan baris
\r pemulangan pengangkutan
\f bentuk suapan
\a isyarat bunyi
\e melarikan diri (ingat troff)
\033 aksara oktal (fikir PDP-11)
\x1B watak heksadesimal
\c[ watak kawalan
\l tukar aksara seterusnya kepada huruf kecil (ingat vi)
\u tukar aksara seterusnya kepada huruf besar (ingat vi)
\L tukar kepada huruf kecil sehingga \E(ingat vi)
\U tukar kepada huruf besar sehingga \E(ingat vi)
\E akhir perubahan kes (ingat vi)
\Q metakarakter topeng regexp sebelum ini \E

selain itu, Perl mentakrifkan metakarakter berikut:

Sila ambil perhatian bahawa \w sepadan dengan satu aksara alfanumerik, bukan keseluruhan perkataan. Untuk memadankan perkataan yang anda mesti gunakan \w+. Metacharacters \w, \W, \s, \S, \d Dan \D boleh digunakan apabila menentukan kelas aksara (tetapi bukan sebagai salah satu sempadan julat).

Perl mentakrifkan yang berikut pernyataan panjang sifar (penegasan lebar sifar):

sempadan perkataan ( \b) ditakrifkan sebagai titik di antara dua aksara, di satu sisinya adalah \w, dan sebaliknya - \W(dalam sebarang susunan), mempertimbangkan permulaan dan akhir khayalan baris aksara untuk dipadankan \W. (Dalam kelas watak \b mewakili ruang belakang, bukan sempadan perkataan.) Metacharacters \A Dan \Z serupa" ^ "Dan" $ ", tetapi tidak akan dipadankan beberapa kali apabila menggunakan pengubah suai /m, sedangkan" ^ "Dan" $ " akan sepadan dengan sempadan setiap baris dalaman. Untuk menentukan padanan dengan hujung baris sebenar, tanpa mengecualikan aksara suapan baris, anda boleh menggunakan \Z(?!\n).

Apabila menggunakan binaan kurungan (...) , \<цифра> sepadan <цифра> subrentetan ke-. Di luar corak, sentiasa gunakan sebelum nombor " $ "sebaliknya" \ ". (Rekod \<цифра> mungkin dalam kes yang jarang berlaku kebakaran di luar corak semasa, tetapi tidak boleh dipercayai. Lihat di bawah.) Skop $ (dan $` , $& Dan $" ) memanjang ke penghujung blok atau garisan tertutup yang sedang dinilai, atau sehingga padanan corak yang berjaya seterusnya, yang mana dahulu. Jika anda ingin menggunakan kurungan untuk mengekang subcorak (seperti set alternatif) tanpa mengingatnya sebagai subcorak, nyatakan ? selepas (.

Anda boleh menggunakan sebarang bilangan kurungan. Jika terdapat lebih daripada 9 subrentetan, pembolehubah $10 , $11 , ... akan merujuk kepada subrentetan yang sepadan. Dalam templat \10 , \11 dan lain-lain. rujuk subrentetan yang telah dipadankan jika sudah terdapat begitu banyak daripadanya sebelum rujukan belakang ini. Jika tidak (untuk keserasian ke belakang) \10 bertepatan dengan \010 , atau simbol penyembelihan, dan \11 bertepatan dengan \011 , watak tab. Dan sebagainya. (Urutan daripada \1 sebelum ini \9 sentiasa dianggap sebagai pautan balik.)

$+ mengembalikan konstruk terakhir dalam kurungan yang dipadankan. $& mengembalikan keseluruhan rentetan yang dipadankan. (Sebelum ini ia digunakan untuk ini $0 , tetapi tidak lagi digunakan.) $` mengembalikan semua yang datang sebelum permulaan rentetan yang dipadankan. $" mengembalikan semua yang datang selepas rentetan yang dipadankan. Contoh:

S/^([^ ]*) *([^ ]*)/$2 $1/; # tukar # dua perkataan pertama jika (/Masa: (..):(..):(..)/) ( $jam = $1; $minit = $2; $saat = $3; )

Ambil perhatian bahawa semua aksara meta yang didahului oleh garis sengkang terbalik dalam Perl adalah abjad angka, mis. \b, \w, \n. Tidak seperti sesetengah bahasa ungkapan biasa, garis segaris tidak mendahului aksara meta bukan abjad angka. Oleh itu, semua pembinaan bentuk \\ , \(, \) , \< , \> , \{ atau \} sentiasa ditafsirkan sebagai aksara literal dan bukan sebagai watak meta. Ini menjadikannya lebih mudah untuk melepaskan rentetan yang anda mahu gunakan sebagai corak tetapi yang anda bimbang mungkin mengandungi metakarakter. Hanya melarikan diri semua aksara bukan abjad angka:

$pattern =~ s/(\W)/\\$1/g;

Anda juga boleh menggunakan fungsi terbina dalam untuk ini quotemeta(). Cara yang lebih mudah untuk melepaskan watak meta secara langsung dalam operator yang sepadan adalah seperti berikut:

/$unquoted\Q$quoted\E$unquoted/

Perl 5 mentakrifkan sintaks sambungan yang konsisten untuk ungkapan biasa. Ini dilakukan menggunakan sepasang kurungan dengan tanda soal sebagai aksara pertama (ini adalah ralat sintaks dalam Perl 4). Watak selepas tanda soal menentukan fungsi pengembangan. Beberapa sambungan disokong:

(?#teks)

Satu komen. Teks diabaikan. Jika suis digunakan /x untuk memasukkan ruang pemformatan, nyatakan sahaja # .

(?:regexp) Kumpulan elemen serupa dengan " () ", tetapi tidak mencipta pautan balik seperti " () ". Oleh itu belah(/\b(?:a|b|c)\b/)

serupa

Pisahkan(/\b(a|b|c)\b/)

tetapi tidak menjana medan tambahan.

(?=regexp) Pandangan positif ke hadapan dengan panjang sifar. Sebagai contoh, /\w+(?=\t)/ sepadan dengan perkataan diikuti dengan aksara tab, tetapi tab itu tidak disertakan $& .
(?!regexp) Pandangan negatif pada panjang sifar. Sebagai contoh, /foo(?!bar)/ sepadan dengan sebarang kejadian " foo"itu tidak mengikuti" bar". Sila ambil perhatian, walau bagaimanapun, pandangan ke hadapan dan ke hadapan adalah BUKAN perkara yang sama. Anda tidak boleh menggunakan binaan ini untuk melihat ke belakang: /(?!foo)bar/ tidak akan menemui entri " bar"yang tidak datang sebelum ini" foo“.Ini berlaku kerana (?! foo) bermakna tiada lagi garisan lagi" foo"- dan dia tidak pergi, dia pergi" bar", Itulah sebabnya " foobar" akan sepadan dengan corak ini. Anda perlu menentukan sesuatu seperti /(?foo)...bar/. "Suka" - kerana sebelum " bar" mungkin bukan tiga aksara. Kes ini boleh dilindungi seperti berikut: /(?:(?!foo)...|^..?)bar/. Kadangkala lebih mudah untuk menulis: jika (/foo/ && $` =~ /bar$/)
(?imsx) Satu atau lebih pengubah suai padanan corak terbina dalam. Ini amat berguna untuk corak yang ditakrifkan dalam jadual berasingan, di mana sesetengah mesti sensitif huruf besar dan yang lain tidak. Untuk aksara sensitif huruf besar-besaran, hanya dayakan (?i) sebelum templat. Contohnya: $pattern = "foobar"; jika (/$pattern/i) # cara yang lebih fleksibel: $pattern = "(?i)foobar";
jika (/$pattern/)

Tanda soal untuk ini dan binaan padanan minima baharu telah dipilih kerana 1) tanda soal jarang dilihat dalam ungkapan biasa sebelumnya dan 2) apabila anda melihat tanda soal, anda perlu berhenti dan "bertanya" kepada diri sendiri apa yang sebenarnya berlaku . ini psikologi...

Ungkapan Biasa: Menjejak ke belakang

Sifat asas padanan ungkapan biasa adalah berkaitan dengan konsep yang dipanggil backtracking, yang digunakan (jika perlu) oleh semua pengkuantiti ungkapan biasa, iaitu * , *? , + , +? , (n,m) Dan (n,m)?.

Untuk ungkapan biasa untuk memadankan corak, ia mesti dipadankan secara keseluruhan, bukan hanya sebahagian. Oleh itu, jika permulaan corak yang mengandungi pengkuantiti berjaya dipadankan supaya corak yang lain tidak dipadankan, enjin yang sepadan akan kembali dan mengira semula bahagian permulaan—maka dinamakan backtracking.

Berikut ialah contoh carian menjejak ke belakang: Katakan anda ingin mencari perkataan yang datang selepas " foo" dalam barisan " Makanan ada di atas meja foo.":

$_ = "Makanan ada di atas meja foo."; jika (/\b(foo)\s+(\w+)/i) ( cetak "$2 mengikuti $1.\n"; )

Apabila melakukan perlawanan pada bahagian pertama ungkapan biasa ( \b(foo)) terdapat kemungkinan padanan tepat pada permulaan baris, semasa dalam $1 nilai " akan diletakkan Foo". Bagaimanapun, sebaik sahaja enjin yang sepadan melihatnya selepas disimpan dalam $1 nilai" Foo"Tiada ruang, ia akan menyedari kesilapannya dan bermula semula pada watak seterusnya selepas perlawanan yang gagal. Kali ini ia akan pergi sehingga kejadian seterusnya " foo". Seluruh ungkapan biasa secara keseluruhan kini dipadankan dan akan menghasilkan hasil yang diharapkan," jadual mengikut foo.".

Kadangkala padanan minimum boleh menjadi sangat berguna. Katakan anda perlu mencari semua yang berlaku di antara baris " foo"Dan" bar". Anda boleh menulis sesuatu seperti:

$_ = "Makanan berada di bawah bar di kandang."; jika (/foo(.*)bar/) ( cetak "dapat<$1>\n"; )

Apa, mungkin secara tidak dijangka, menghasilkan:

Dapat

Ini berlaku kerana templat .* adalah tamak, jadi anda mendapat segala-galanya dari yang pertama" foo"sehingga yang terakhir" bar". Dalam kes ini, adalah lebih cekap untuk menggunakan padanan minimum, memastikan anda mendapat teks antara " foo"dan kejadian pertama" bar" selepas dia.

Jika (/foo(.*?)bar/) ( cetak "dapat<$1>\n") mendapat

Berikut ialah satu lagi contoh: katakan anda ingin mencari nombor pada penghujung rentetan dan mengekalkan bahagian yang dipadankan sebelumnya. Anda menulis perkara berikut:

$_ = "Saya ada 2 nombor: 53147";
jika (/(.*)(\d*)/) ( #Error! print "Permulaan ialah<$1>,nombor ialah<$2>.\n"; )

Ini tidak akan berfungsi sama sekali kerana templat .* tamak dan memakan seluruh barisan. Kerana ia \d* boleh memadankan rentetan kosong, keseluruhan ungkapan biasa secara keseluruhan berjaya dipadankan.

Permulaan ialah ,nombor ialah<>.

Berikut ialah beberapa lagi pilihan, kebanyakannya tidak akan berfungsi:

$_ = "Saya ada 2 nombor: 53147"; @tepuk = qw( (.*)(\d*) (.*)(\d+) (.*?)(\d*) (.*?)(\d+) (.*)(\d+)$ (.*?)(\d+)$ (.*)\b(\d+)$ (.*\D)(\d+)$ ); untuk $pat (@pats) ( printf "%-12s ", $pat; if (/$pat/) ( print "<$1> <$2>\n"; ) else (cetak "GAGAL\n"; ) ) Hasilnya ialah:
(.*)(\d*) <>(.*)(\d+) <7>(.*?)(\d*)<> <>(.*?)(\d+) <2>(.*)(\d+)$ <7>(.*?)(\d+)$ <53147>(.*)\b(\d+)$ <53147>(.*\D)(\d+)$ <53147>

Seperti yang anda lihat, semua ini boleh menjadi sedikit rumit. Adalah penting untuk memahami bahawa ungkapan biasa hanyalah satu set pernyataan yang menentukan hasil yang berjaya. Boleh 0, 1 atau lebih dalam pelbagai cara memenuhi definisi pada baris tertentu. Dan jika terdapat beberapa perlawanan yang berjaya, anda perlu memahami backtracking untuk mengetahui perlawanan yang berjaya akan diperolehi.

Apabila menggunakan pandangan dan penafian, keadaan boleh menjadi lebih rumit. Katakan anda ingin mencari urutan aksara selain daripada nombor yang tidak diikuti oleh " 123 ". Awak boleh cuba tulis macam ni

$_ = "ABC123"; jika (/^\D*(?!123)/) ( # Ralat! cetak "Ya, tiada 123 dalam $_\n"; )

Tetapi tidak akan ada hasil; sekurang-kurangnya tidak seperti yang anda harapkan. Ditegaskan bahawa tidak ada 123 . Berikut ialah gambaran yang lebih jelas tentang sebab, bertentangan dengan jangkaan popular, perbandingan itu berlaku:

$x = "ABC123" ; $y = "ABC445" ; cetak "1: mendapat $1\n" jika $x =~ /^(ABC)(?!123)/ ; cetak "2: mendapat $1\n" jika $y =~ /^(ABC)(?!123)/ ; cetak "3: mendapat $1\n" jika $x =~ /^(\D*)(?!123)/ ; cetak "4: mendapat $1\n" jika $y =~ /^(\D*)(?!123)/ ;

Akan dikeluarkan

2: mendapat ABC 3: mendapat AB 4: mendapat ABC

Anda mungkin menjangkakan ujian 3 akan gagal kerana ia nampaknya merupakan versi 1 yang lebih generik. Perbezaan penting antara keduanya ialah ujian 3 mengandungi pengkuantiti (\D*) dan oleh itu boleh menggunakan backtracking manakala cek 1 tidak boleh. Apa yang anda benar-benar bertanya ialah: "Adakah benar pada mulanya $x, selepas 0 atau lebih bukan digit, datang sesuatu selain daripada 123 Jika mekanisme pemadanan membenarkan \D* berkembang kepada " ABC", keseluruhan corak tidak akan dipadankan. Enjin carian pada mulanya akan sepadan \D* dengan " ABC". Kemudian dia akan cuba sepadan (?!123) c" 123 ", yang, sudah tentu, adalah mustahil. Tetapi kerana pengkuantiti digunakan dalam ungkapan biasa (\D*), enjin carian mungkin kembali dan mencari padanan lain dengan harapan dapat mencari padanan untuk keseluruhan ungkapan biasa.

Kini, memandangkan padanan corak sangat diingini oleh enjin carian, ia menggunakan pulangan standard dan cuba lagi regexp(undur-dan-cuba semula) dan benarkan masa ini \D* berkembang hanya kepada " AB"Sekarang ada sesuatu selepas itu" AB", yang tidak bertepatan dengan " 123 ". Ini" C123", yang cukup memuaskan.

Anda boleh mengatasinya dengan menggunakan penegasan dan penolakan bersama-sama. Kami akan mengatakan bahawa selepas bahagian pertama dalam $1 mesti ada nombor, tetapi mesti ada sesuatu selain daripada " 123 ". Ingat bahawa pandangan ke hadapan ialah ungkapan sifar panjang - padanan hanya menjalankan ujian, tetapi tidak mengambil bahagian daripada rentetan. Selepas perubahan sedemikian, hasil yang diingini akan diperoleh; iaitu dalam kes 5 - kegagalan, dan dalam kes 6 - kejayaan:

Cetak "5: mendapat $1\n" jika $x =~ /^(\D*)(?=\d)(?!123)/ ; cetak "6: mendapat $1\n" jika $y =~ /^(\D*)(?=\d)(?!123)/ ; 6: Mendapat ABC

Dengan kata lain, dua pernyataan panjang sifar(penegasan lebar sifar) dalam satu baris berfungsi seolah-olah konjungsi mereka sedang diuji, sama seperti mana-mana penegasan terbina dalam: corak /^$/ sepadan hanya jika anda berada di awal baris DAN penghujung baris pada masa yang sama. Sebab yang lebih mendalam untuk perkara ini ialah kedekatan dalam ungkapan biasa sentiasa bermaksud DAN, kecuali apabila secara eksplisit menunjukkan ATAU menggunakan paip. /ab/ bermaksud membandingkan" a"Dan (kemudian) padankan" b", walaupun percubaan perbandingan dibuat dalam kedudukan yang berbeza, kerana " a" ialah pernyataan yang tidak panjangnya sifar, tetapi panjangnya satu.

Satu amaran: Ungkapan biasa yang sangat kompleks mungkin memerlukan masa pemadanan eksponen disebabkan oleh bilangan yang banyak pilihan yang mungkin padanan dalam carian menjejak ke belakang. Sebagai contoh, corak berikut akan mengambil masa yang sangat lama untuk dipadankan

/((a(0.5))(0.5))(0.5)/

Dan jika anda menggunakan * Daripada mengehadkan bilangan kejadian daripada 0 hingga 5, perlawanan akan berjalan selama-lamanya -- atau sehingga ruang tindanan habis.

Ungkapan biasa versi 8

Jika anda tidak biasa dengan fungsi perpustakaan "standard". regexp versi 8, berikut ialah peraturan padanan corak yang tidak diterangkan di atas.

Mana-mana aksara tunggal sepadan dengan dirinya melainkan watak meta yang mempunyai makna istimewa yang diterangkan di sini atau di atas. Watak yang biasanya bertindak sebagai watak meta boleh dikehendaki ditafsirkan secara literal dengan menambahkannya dengan " \ " (Sebagai contoh, " \. "perlawanan" . ", bukan sebarang watak; " \\ "perlawanan" \ "). Urutan aksara sepadan dengan jujukan aksara yang sama dalam rentetan sasaran, jadi coraknya blurfl akan sepadan dengan " blurfl" di garisan sasaran.

Anda boleh menentukan kelas aksara dengan melampirkan senarai aksara dalam kurungan segi empat sama yang akan sepadan dengan mana-mana aksara dalam senarai. Jika aksara pertama selepas " [ " - "^ ", kelas sepadan dengan mana-mana aksara yang tidak dinyatakan dalam senarai. Dalam senarai, aksara " - " digunakan untuk menunjukkan julat, jadi a-z mewakili semua watak daripada " a"sebelum" z", inklusif.

Aksara boleh ditentukan menggunakan sintaks metacharacter seperti yang digunakan dalam C: " \n" sepadan dengan baris baharu, " \t"- tab," \r"- pemulangan pengangkutan," \f" - suapan borang, dsb. Secara umum, \nnn, Di mana nnn- ialah rentetan digit perlapanan, sepadan dengan aksara yang nilai kod ASCIInya ialah - nnn. Begitu juga, \xnn, Di mana nn- ini adalah digit heksadesimal, sepadan dengan aksara yang nilai kod ASCIInya ialah - nn. Ungkapan \cx sepadan watak ASCII kawalan-x. Akhirnya, metacharacter " . " sepadan dengan mana-mana watak kecuali " \n" (kecuali digunakan /s).

Anda boleh menentukan satu set alternatif untuk templat, memisahkannya dengan metacharacter " | ", Jadi bayaran|fie|musuh akan sepadan dengan mana-mana subrentetan " Bayaran", "fie"atau" musuh" dalam rentetan sasaran (sama seperti f(e|i|o)e). Ambil perhatian bahawa alternatif pertama merangkumi segala-galanya daripada pemisah corak terakhir (" (", "[ " atau dari permulaan corak) kepada aksara pertama " | ", dan alternatif terakhir termasuk segala-galanya daripada watak terakhir "| " ke pembatas corak seterusnya. Oleh itu, alternatif biasanya diletakkan dalam kurungan untuk memastikan tiada keraguan di mana ia bermula dan berakhir. Walau bagaimanapun, ambil perhatian bahawa dalam kurungan persegi " | " ditafsirkan sebagai literal, jadi jika anda menulis , perbandingan hanya akan berlaku dengan .

Dalam templat, anda boleh menyerlahkan subtemplat (dengan meletakkannya dalam kurungan) untuk rujukan selanjutnya dan anda boleh memaut kembali ke n subcorak ke kemudian menggunakan metacharacter \n. Subcorak dinomborkan dari kiri ke kanan menggunakan kurungan pembukaan. Ambil perhatian bahawa rujukan belakang sepadan dengan subpola dalam baris yang dipersoalkan, bukan peraturan yang mentakrifkan subpola itu. sebab tu (0|0x)\d*\s\1\d* akan sepadan dengan " 0x1234 0x4321"tetapi tidak dengan" 0x1234 01234" kerana subcorak 1 sebenarnya sepadan " 0x"walaupun peraturan 0|0x berkemungkinan sepadan dengan 0 awal dalam nombor kedua.

AMARAN tentang \1 dan $1

Sesetengah orang terlalu biasa menulis perkara seperti

$pattern =~ s/(\W)/\\\1/g;

Akar tabiat ini kembali ke sebelah kanan pengendali penggantian sed, tetapi ia adalah tabiat buruk. Maksudnya ialah dari sudut pandangan Perl bahagian kanan s/// ialah rentetan dalam petikan berganda. \1 V talian biasa dalam petikan berganda bermaksud kawalan-A. Nilai Unix biasa \1 disimpan dalam s///. Walau bagaimanapun, jika anda membiasakan diri melakukannya dengan cara ini, anda akan menghadapi masalah menambah pengubah suai /e.

S/(\d+)/ \1 + 1 /cth; atau jika anda cuba melakukan s/(\d+)/\1000/;

Kekaburan ini tidak dapat dielakkan dengan menulis \{1}000 , tetapi mungkin jika anda menulis ${1}000 . Cuma operasi interpolasi tidak boleh dikelirukan dengan operasi pemadanan rujukan belakang. Sudah tentu mereka mempunyai makna yang berbeza di sebelah kiri pengendali s///.

Bab ini menerangkan sintaks ungkapan biasa. Penggunaan paling biasa mereka dalam Perl adalah dalam mencari dan menggantikan pengendali seperti s//, m/, pengendali penghubung =~ atau != dan lain-lain. Sebagai peraturan, semua pengendali ini mempunyai pilihan yang sama seperti:

Biasanya semua pilihan ini dilambangkan sebagai "/x". Mereka juga boleh digunakan di dalam templat menggunakan reka bentuk baru (?...)

Ungkapan atau corak biasa adalah sama seperti prosedur regexp dalam Unix. Ungkapan dan sintaks dipinjam daripada prosedur V8 yang diedarkan secara bebas oleh Henry Spencer, di mana ia diterangkan secara terperinci.

Templat menggunakan metacharacter berikut (aksara yang menunjukkan kumpulan aksara lain) yang sering dipanggil standard egrep:

Metacharacter mempunyai pengubah suai (ditulis selepas metacharacter):

Dalam semua kes lain, pendakap kerinting dianggap sebagai aksara biasa (biasa). Oleh itu "*" bersamaan dengan (0,) , "+" ialah (1,) dan "?" - (0.1). n dan m tidak boleh lebih besar daripada 65536.

Secara lalai, metacharacter adalah tamak. Perlawanan disebarkan sebanyak mungkin, tanpa mengambil kira kesan metakarakter seterusnya. Jika anda ingin "mengurangkan selera makan mereka", gunakan simbol "?". Ini tidak mengubah maksud metacharacters, ia hanya mengurangkan penyebaran. Oleh itu:

Templat berfungsi dengan cara yang sama seperti petikan berganda, jadi anda boleh menggunakan `\` - simbol (simbol sengkang belakang) di dalamnya:

\t - watak tab
\n - baris baru
\r - pemulangan pengangkutan
\A - terjemahan format
\v - penjadualan menegak
\a - panggil
\e - melarikan diri
\033 - notasi simbol oktal
\x1A - perenambelasan
\c[ - simbol kawalan
\l - huruf kecil seterusnya aksara
\u - huruf besar -//-
\L - semua aksara adalah huruf kecil hingga \E
\U - di bahagian atas -//-
\E - daftar penghad perubahan
\Q - membatalkan tindakan sebagai metacharacter

Selain itu, metakarakter berikut telah ditambahkan pada Perl:

Ambil perhatian bahawa ini semua adalah "satu" watak. Gunakan pengubah suai untuk menunjukkan urutan. Jadi:

Di samping itu, terdapat metakarakter khayalan. Menandakan simbol yang tidak wujud di tempat nilai berubah. Seperti:

Sempadan perkataan (\b) ialah titik khayalan antara aksara \w dan \W. Dalam kelas aksara, "\b" mewakili aksara ruang belakang. Metacharacters \A Dan \Z- “^” dan “$” adalah serupa, tetapi jika permulaan baris"^" dan baris berakhir "$" bertindak untuk setiap baris dalam rentetan berbilang baris, kemudian \A Dan \Z menunjukkan permulaan dan penghujung keseluruhan rentetan berbilang baris.

Jika pengumpulan (kurungan) digunakan dalam corak, maka nombor subrentetan kumpulan ditetapkan sebagai "\digit". Ambil perhatian bahawa mengikut corak dalam ungkapan atau blok, kumpulan ini dilambangkan sebagai "$digit". Di samping itu, terdapat pembolehubah tambahan:

Contoh:

$s = "Satu 1 dua 2 dan tiga 3"; jika ($s =~ /(\d+)\D+(\d+)/) ( cetak "$1\n"; # Hasil "1" cetak "$2\n"; # "2" cetak "$+\n" ; # "2" cetak "$&\n"; # "1 dua 2" cetak "$`\n"; # "Satu " cetak "$"\n"; # "dan tiga 3" )

Perl versi 5 mengandungi binaan templat tambahan:

Contoh:

$s = "1+2-3*4"; if ($s =~ /(\d)(?=-)/) # Cari nombor diikuti dengan "-" ( print "$1\n"; # Hasil "2" ) else ( print "ralat carian\n" ;) (?!corak) - "memandang" ke hadapan pada penafian.

Contoh:

$s = "1+2-3*4"; if ($s =~ /(\d)(?!\+)/) # Cari digit yang tidak diikuti oleh "+" ( print "$1\n"; # Hasil "2" ) else ( print "search ralat\n";)

(?ismx) - pengubah "dalaman". Ia mudah digunakan dalam templat, di mana, sebagai contoh, anda perlu menentukan pengubah suai di dalam templat.

Peraturan ungkapan biasa. (regex)

  1. Mana-mana watak mewakili dirinya melainkan ia adalah metacharacter. Jika anda perlu membatalkan kesan metacharacter, letakkan "\" di hadapannya.
  2. Rentetan aksara menandakan rentetan aksara ini.
  3. Set aksara yang mungkin (kelas) disertakan dalam kurungan segi empat sama "", ini bermakna bahawa salah satu aksara yang dinyatakan dalam kurungan boleh muncul di tempat ini. Jika aksara pertama dalam kurungan ialah “^”, maka tiada satu pun aksara yang ditentukan boleh muncul pada titik ini dalam ungkapan. Dalam kelas, anda boleh menggunakan simbol "-" untuk menandakan julat aksara. Contohnya, a-z ialah salah satu huruf kecil abjad Latin, 0-9 ialah nombor, dsb.
  4. Semua aksara, termasuk yang istimewa, boleh dilambangkan menggunakan "\" seperti dalam bahasa C.
  5. Urutan ganti dipisahkan dengan "|" Ambil perhatian bahawa di dalam kurungan segi empat sama ini adalah simbol biasa.
  6. Dalam ungkapan biasa, anda boleh menentukan "subpola" dengan melampirkannya dalam kurungan dan merujuknya sebagai "\number" Kurungan pertama ditetapkan "\1".
  1. Gantikan berbilang ruang dan aksara bukan teks dengan ruang tunggal:

    $text = "Ini adalah teks."
    $text =~ tr[\000-\040\177\377][\040]s;
    cetak $teks;
    Berikut adalah teksnya.

  2. Potong dua, tiga, dsb. surat:

    $text = "Ini adalah texxxxxxt.";
    $teks =~ tr/a-zA-Z/s;
    cetak $teks;
    Berikut adalah teksnya.

  3. Kira semula bilangan aksara bukan huruf:

    $xcount=($text =~ tr/A-Za-z//c);

  4. Kosongkan bit kelapan aksara, alih keluar aksara bukan teks:

    $teks =- tr(\200-\377)(\000-\l77);
    $text =~ tr[\000-\037\177]d;

  5. Gantikan aksara bukan teks dan 8-bit dengan ruang tunggal:

    $text =~ tr/\021-\176/ /cs;

Cari perkataan individu

Untuk menyerlahkan perkataan, anda boleh menggunakan metacharacter \S untuk memadankan aksara bukan ruang putih:

$text = "Sekarang adalah masanya.";
$teks =- /(\S+)/;
cetakan ;
Sekarang

Walau bagaimanapun, metakarakter \S juga sepadan dengan aksara yang biasanya tidak digunakan untuk pengecam. Untuk memilih perkataan yang terdiri daripada huruf Latin, nombor dan garis bawah, anda perlu menggunakan metacharacter \w:

$text = "Sekarang adalah masanya.";
$teks =~ /(\w+)/;
cetakan ;
Sekarang

Jika anda ingin memasukkan hanya huruf Latin dalam carian, anda mesti menggunakan kelas aksara:

$text = "Sekarang adalah masanya.";
$teks =~ /(+)/;
cetakan ;
Sekarang

Lagi kaedah selamat adalah untuk memasukkan aksara sempadan perkataan khayalan dalam pola:

$text = "Bagaimana masanya.";
$text=~/\b(+)\b/;
cetakan ;
Sekarang

Snap ke permulaan baris

Permulaan baris sepadan dengan metacharacter (watak khayalan) ^ . Untuk membuat corak pergi ke permulaan baris, anda perlu menetapkan watak ini pada permulaan ungkapan biasa. Sebagai contoh, ini adalah cara anda boleh menyemak bahawa teks tidak bermula dengan noktah:

$line = ".Hello!";
if($line=~m/^\./)(
cetak "Tidak boleh memulakan ayat dengan noktah!\n";
}
Tidak sepatutnya memulakan ayat dengan titik!

Untuk mengelakkan tempoh yang dinyatakan dalam corak daripada ditafsirkan sebagai metacharacter, adalah perlu untuk mendahuluinya dengan garis serong ke belakang.

Snap ke hujung baris

Untuk menambat corak ke hujung rentetan, metacharacter (watak khayalan) $ digunakan. Dalam contoh kami, kami menggunakan pengikatan corak pada permulaan dan penghujung baris untuk memastikan bahawa pengguna hanya memasukkan perkataan "keluar":

sementara(<>){
if(m/"exlt$/) (keluar;)
}

Mencari nombor

$test = "Hello!";
if($text =~ /\D/)(
cetak "Ia bukan nombor.\n";
}
Ia bukan nombor.

Perkara yang sama boleh dilakukan menggunakan \d metacharacter:

$text = "333";
if($teks =~ /^\d+$/)(
cetak "Ia ialah nombor.\n";
}
Ia adalah nombor.

Anda boleh meminta nombor itu mengikut format biasa. Iaitu, nombor boleh mengandungi titik perpuluhan, didahului oleh sekurang-kurangnya satu digit dan mungkin beberapa digit selepasnya:

$text = "3.1415926";
if($text =~ /^(\d+\.\d*|\d+)$/)(
cetak "Ia ialah nombor.\n";
}
Ia adalah nombor.

Di samping itu, apabila menyemak, anda boleh mengambil kira hakikat bahawa nombor itu boleh didahului oleh sama ada tambah atau tolak (atau ruang kosong):

$teks = "-2.7182";
jika ($teks =~ /^([+-]*\d+)(\.\d*|)$/) (
cetak "Ia ialah nombor.\n";

Memandangkan tambah adalah metacharacter, ia mesti dilindungi dengan garis miring ke belakang. Walau bagaimanapun, di dalam kurungan segi empat sama, iaitu kelas aksara, ia tidak boleh menjadi pengkuantiti. Tanda tolak dalam kelas aksara lazimnya bertindak sebagai pengendali julat dan oleh itu mesti dilepaskan dengan garis miring ke belakang. Walau bagaimanapun, pada permulaan atau penghujung corak, ia tidak boleh menunjukkan julat dalam apa jua cara, dan oleh itu garis miring ke belakang adalah pilihan. Akhir sekali, ujian yang lebih ketat memerlukan tanda, jika ada, hanya satu:

$teks = "+0.142857142857142857";
jika ($teks =~ /^(+|-|)\d+(\.\d*\)$/) (
cetak "Ia ialah nombor.\n";
}
Ia adalah nombor.

Corak alternatif, jika ada, ditandakan dari kiri ke kanan. Carian untuk pilihan tamat sebaik sahaja padanan ditemui antara teks dan templat. Oleh itu, sebagai contoh, susunan alternatif dalam corak (\.\d*|) boleh menjadi kritikal jika bukan untuk pengikatan hujung baris. Akhir sekali, berikut ialah cara untuk menyemak bahawa teks ialah nombor perenambelasan tanpa tanda atau atribut lain:

$teks = "1AO";
melainkan (fteks =~ m/^+$/) (
cetak "Ia bukan nombor heks,\n";
}

pengesahan ID

Anda boleh menggunakan metakarakter \w untuk menyemak sama ada teks hanya terdiri daripada huruf, nombor dan garis bawah (inilah yang dipanggil perl sebagai aksara perkataan):

$text="abc";
if($text=~/^\w+$/)(
cetak "Hanya aksara perkataan ditemui.\n";
}
Hanya aksara perkataan ditemui.

Walau bagaimanapun, jika anda ingin memastikan bahawa teks mengandungi huruf Latin dan tidak mengandungi nombor atau garis bawah, anda perlu menggunakan corak yang berbeza:

$text = "abc";
if($text=~ /^+$/) ( cetak "Hanya aksara huruf ditemui.\n"; )
Aksara huruf Qnly ditemui.

Akhir sekali, untuk memastikan bahawa teks ialah pengecam, iaitu, ia bermula dengan huruf dan mengandungi huruf, nombor dan garis bawah, anda boleh menggunakan arahan:

$text = "X125c";
if($text=~ /^\w+$/) (
cetak "Ini ialah pengecam.\n";
}
Ini adalah pengecam.

Bagaimana untuk mencari berbilang padanan

Anda boleh menggunakan pengubah suai g untuk memadankan berbilang kejadian corak. Contoh berikut, yang kita lihat sebelum ini, menggunakan perintah m/.../ dengan pengubah g untuk mencari semua kemunculan huruf x dalam teks:

$text="Ini adalah texxxxxt";
while($text=~m/x/g) (
cetak "Terjumpa x lain.\n";
}
Terjumpa x lagi.
Terjumpa x lagi.
Terjumpa x lagi.
Terjumpa x lagi.
Terjumpa x lagi.

Pengubah suai g menjadikan carian global. Dalam konteks (skalar) tertentu, perl ingat di mana ia berhenti pada baris apabila carian sebelumnya. Carian seterusnya diteruskan dari titik tertunda. Tanpa pengubah g, perintah m/.../ akan mencari kejadian pertama huruf x secara degil, dan gelung akan berterusan selama-lamanya.

Berbeza dengan perintah m/.../, perintah s/.../.../ dengan pengubah g berfungsi penggantian global pada satu masa, berfungsi seolah-olah ia sudah mempunyai gelung carian terbina dalam seperti yang di atas. Contoh berikut menggantikan semua kejadian x dengan z sekaligus:

$text = "Ini adalah texxxxxxt.";
$teks =~ s/x/z/g;
cetak $teks;
Inilah tezzzzt.

Tanpa pengubah g, arahan s/.../.../ hanya akan menggantikan huruf pertama x. Perintah s/.../.../ mengembalikan bilangan penggantian yang dibuat, yang boleh berguna:

$text= "Ini adalah texxxxxt.";
cetak (teks =~ s/x/z/g)
5

Mencari padanan yang tidak peka huruf besar-besaran

Anda boleh menggunakan pengubah suai i untuk menjadikan carian tidak sensitif terhadap perbezaan antara huruf besar dan huruf kecil. Dalam contoh berikut, atur cara mengulangi teks yang dimasukkan pengguna pada skrin sehingga Q atau q (singkatan untuk QUIT atau quit) dimasukkan, di mana program keluar:

sementara(<>) {
chomp;
melainkan (/^q$/i)( print
) lain (
keluar;
}
}

Pemilihan subrentetan

Untuk mendapatkan subrentetan teks yang ditemui, anda boleh menggunakan kurungan dalam badan templat. Jika ini lebih mudah, anda juga boleh menggunakan fungsi terbina dalam substr. Dalam contoh berikut, kami memotong jenis produk yang kami perlukan daripada rentetan teks:

$record = "Nombor produk:12345
Jenis produk: pencetak
Harga produk: 5";
if($record=~/Jenis produk:\s*(+)/i)(
cetak "Jenis produk ialah^.\n";
}
jenis produk ialah pencetak.

Memanggil fungsi dan menilai ungkapan apabila menggantikan teks

Dengan menggunakan pengubah suai e untuk perintah s/.../.../, anda menunjukkan bahawa operan sebelah kanan (iaitu, teks yang digantikan) ialah ungkapan perl yang perlu dinilai. Sebagai contoh, anda boleh menggunakan fungsi terbina dalam perl uc (huruf besar) untuk menggantikan semua huruf kecil perkataan dalam rentetan dengan huruf besar:

$text = "Sekarang adalah masanya.";
$text=~ s/(\w+)/uc()/ge;
cetak $teks;
SEKARANG MASANYA.

Daripada fungsi uc($l), anda boleh meletakkan kod sewenang-wenangnya, termasuk panggilan program.

Mencari perlawanan ke-n

Pengubah suai g digunakan untuk lelaran melalui semua kejadian corak tertentu. Tetapi apakah yang perlu anda lakukan jika anda memerlukan titik kebetulan yang sangat spesifik dengan templat, contohnya, yang kedua atau ketiga? Operator gelung semasa dalam kombinasi dengan kurungan yang menyerlahkan corak yang diingini akan membantu anda:

$text = "Nama:Anne Nanie:Burkart Nama:Glaire Nama: Dan";
manakala ($teks =~ /Nama: \s*(\w+)/g) (
+$perlawanan;
cetak "Nombor padanan $padanan ialah .\n";
}

Perlawanan nombor 1 ialah Anne
Perlawanan nombor 2 ialah Burkart
Perlawanan nombor 3 ialah Claire
Perlawanan nombor 4 ialah Dan

Contoh ini boleh ditulis semula menggunakan untuk gelung:

$text = "Nama:Anne Nama:Burkart Nama:Ciaire Nama:Dan";
untuk ($perlawanan = 0;
$text =~ /Nama:\s*(\w+)/g;
cetak "Nombor padanan $(\match) ialah .\n")
{}
Perlawanan nwber 1 Adakah Anne
Perlawanan nombor 2 ialah Burkart
Perlawanan nombor 3 ialah Claire
Perlawanan nombor 4 ialah Dan

Jika anda perlu menentukan padanan yang diingini bukan dengan nombor, tetapi dengan kandungan (contohnya, dengan huruf pertama nama pengguna), maka bukannya pembilang $match, anda boleh menganalisis kandungan pembolehubah yang dikemas kini dengan setiap perlawanan ditemui. Apabila anda ingin menggantikan, bukannya mencari, kejadian kedua atau ketiga teks, anda boleh menggunakan skema yang sama, menggunakan sebagai badan gelung ungkapan perl yang dipanggil untuk menilai rentetan gantian:

$text = "Nama:Anne Nama:Nama Burkart:Nama Claire:Dan";
$padanan =0;
$text =~ s/(Nama:\s*(\w+))/ # kod perl bermula
if (++$match == 2) ( # pembilang kenaikan
"Nama:John ()" # kembalikan nilai baharu
) else ( )# kekalkan nilai lama
/gex;
cetak $teks;
Nama:Anne Nama:John (Burkart) Nama:ClaireNama:Dan

Semasa carian global, untuk setiap padanan yang ditemui, ungkapan yang dinyatakan sebagai operan kedua dinilai. Apabila mengiranya, nilai pembilang dinaikkan, dan bergantung padanya, sama ada nilai teks lama atau yang baharu digantikan sebagai pengganti. Pengubah suai x membolehkan anda menambah ulasan pada medan templat, menjadikan kod lebih telus. Sila ambil perhatian bahawa kami perlu menyertakan keseluruhan corak dalam kurungan untuk mendapatkan nilai teks yang ditemui dan menggantikannya sepenuhnya.

Bagaimana untuk mengehadkan "ketamakan" pengkuantiti

Secara lalai, pengkuantiti berkelakuan seperti objek tamak. Bermula pada kedudukan carian semasa, mereka mengambil rentetan terpanjang yang boleh dipadankan oleh ungkapan biasa sebelum pengkuantiti. Algoritma penjejakan belakang yang digunakan oleh perl mampu mengehadkan selera pengkuantiti dengan kembali dan mengurangkan panjang rentetan yang ditangkap jika ia tidak dapat mencari padanan antara teks dan corak. Walau bagaimanapun, mekanisme ini tidak selalu berfungsi seperti yang kita inginkan. Pertimbangkan contoh berikut. Kami ingin menggantikan teks "Itu" dengan teks "Itu" s". Namun, disebabkan kerakusan pengkuantiti, ungkapan biasa " .*is " dipadankan dengan serpihan teks dari permulaan baris kepada yang terakhir "adalah" ditemui:


$text =~ s/.*is/That"s/;
cetak $teks;
Itu bukan?

Untuk menjadikan pengkuantiti kurang tamak, iaitu untuk menjadikannya menangkap rentetan minimum yang mana ungkapan biasa boleh dibandingkan, anda perlu meletakkan pengkuantiti selepas pengkuantiti tanda soal. Oleh itu, pengkuantiti mengambil bentuk berikut:

  • *? - sifar atau lebih padanan,
  • +? - satu atau lebih perlawanan,
  • ?? - sifar perlawanan atau satu perlawanan,
  • (n)? - betul-betul n padanan,
  • (n,)? - sekurang-kurangnya n padanan,
  • (n,m)? - sekurang-kurangnya n padanan, tetapi tidak lebih daripada m.

Sila ambil perhatian bahawa ini tidak mengubah maksud pengkuantiti; hanya tingkah laku algoritma carian berubah. Jika, dalam proses memadankan templat dan teks, prototaip ditentukan secara unik, maka algoritma penjejakan ke belakang akan meningkatkan "ketamakan" pengkuantiti sedemikian dengan cara yang sama seperti ia mengehadkan selera pengkuantiti sesamanya. Walau bagaimanapun, jika pilihannya samar-samar, hasil carian akan berbeza:

$text = "Itu adalah beberapa teks, bukan?";
$text =~ s/.*?is/That"s/;
cetak $teks;
Itulah beberapa teks, bukan?

Cara mengalih keluar ruang hadapan dan belakang

Untuk memangkas aksara ruang putih terkemuka daripada rentetan, anda boleh menggunakan arahan berikut:

$text = "Sekarang adalah masanya.";
$teks =~ s/^\s+//;
cetak $teks;
Sekarang adalah masanya.

Untuk memotong ruang belakang, arahan berikut adalah sesuai:

$text = "Sekarang adalah masanya.";
$teks =~ s/\s+$//;
cetak $teks;
Sekarang adalah masanya.

Untuk memangkas kedua-dua ruang hadapan dan belakang, adalah lebih baik untuk memanggil kedua-dua arahan ini secara berurutan daripada menggunakan templat yang memangkas ruang yang tidak diperlukan sekaligus. Oleh kerana prosedur untuk memadankan templat dan teks agak rumit, ini operasi mudah Ia mungkin mengambil masa lebih lama daripada yang anda mahukan.

Sebagai contoh, dalam teks anda perlu mencari teks yang terletak di antara teg pembukaan dan penutup:

$text=" blah blah";
jika($teks=~m!<()>(.*?)/\1!ig) (
cetak "\n";
}

akan menemui semua perkataan antara tag dan .

Ungkapan biasa mempunyai semantik mereka sendiri: kelajuan, tergesa-gesa dan kembali. Jika pengkuantiti * sepadan dalam banyak kes, maka hasil terpanjang akan dicetak. Ini adalah ketamakan. Pantas: Carian cuba mencari secepat mungkin. "Teks"=~/m*/ , bermakna tiada m aksara, tetapi hasilnya nilai 0 akan dikembalikan. Itu. secara rasmi 0 atau lebih aksara.

$test="aaooee ooaao";
$test=~s/o*/e/;
cetak $test;
eaaooee ooaao

kerana 1 elemen tindanan ialah 0 atau lebih aksara.

Jika kita menambah pengkuantiti g , hasilnya akan seperti ini:

Eaeaeeeeee eeaeaee

kerana baris mengandungi 13 tempat di mana o boleh muncul, termasuk yang kosong.

Pengubah suai:

  • /saya abaikan kes
  • /x abaikan ruang dalam corak dan benarkan ulasan.
  • /g pengubah suai untuk membenarkan carian/ganti di mana mungkin
  • /gc kedudukan tidak ditetapkan semula jika carian gagal.
  • /s perlawanan dibenarkan. dengan \n , $* diabaikan.
  • /m benarkan ^ dan $ sepadan untuk permulaan dan akhir baris dalam pemisah baris dalaman
  • /o susun sekali
  • /e sebelah kanan s/// mewakili kod yang sedang dilaksanakan
  • /ee sebelah kanan s/// dilaksanakan, selepas itu nilai pulangan ditafsir semula.

apabila membuat panggilan menggunakan locale, tetapan setempat diambil kira. Pengubah suai /g boleh mengisi tatasusunan nilai @nums = m/(\d+)/g; tetapi ini akan berfungsi untuk perlawanan tidak bertindih. Untuk menangkap padanan anda perlu menggunakan operator?=... Jika lebar = 0, maka mekanisme carian kekal di tempat yang sama. Data yang ditemui kekal di dalam kurungan. Jika terdapat pengubah suai /g, maka kedudukan semasa kekal sama, tetapi bergerak ke hadapan satu aksara.

$numbers="123456789";
@one=$numbers=~/(\d\d\d)/g;
@dua=$nombor=~/(?=(\d\d\d))/g;
cetak "@satu \n";
cetak "@dua\n";

Pengubah suai m dan s diperlukan untuk mencari urutan aksara yang mengandungi baris baharu. Dengan s, titik itu sepadan dengan \n dan mengabaikan $* . m menjadikan ^ dan $ sepadan sebelum dan selepas \n . e sebelah kanan berpuas hati sebagai kod program: perl -i -n -p -e "s/(.)/lc()/g" *.html menukar semua aksara dalam semua *.html fail direktori semasa kepada huruf kecil.

6.4.1. Sintaks ungkapan biasa

Ungkapan Biasa ialah corak untuk mencari kombinasi aksara tertentu dalam rentetan teks dan menggantikannya dengan kombinasi aksara lain (operasi ini dipanggil sewajarnya padanan corak Dan penggantian). Ungkapan biasa dalam PERL kelihatan seperti

/corak/pengubahsuai

Corak di sini ialah rentetan yang mentakrifkan ungkapan biasa dan pengubah suai ialah huruf tunggal pilihan yang menentukan peraturan untuk menggunakan ungkapan biasa ini.

Ungkapan biasa boleh terdiri daripada aksara biasa; dalam kes ini ia akan sepadan dengan gabungan aksara yang diberikan dalam rentetan. Sebagai contoh, ungkapan /cat/ sepadan dengan subrentetan yang diserlahkan dalam baris berikut: " kucing ok", "untuk kucing"," y kucing Walau bagaimanapun, kuasa sebenar ungkapan biasa PERL datang daripada keupayaan untuk menggunakan khas metakarakter.

Jadual 6.9. Metacharacter dalam ungkapan biasa
Simbol Penerangan
\ Bagi watak-watak yang biasanya ditafsirkan secara literal, bermakna watak seterusnya ialah watak meta. Contohnya, /n/ sepadan dengan huruf n dan /\n/ sepadan dengan aksara baris baharu.
Untuk metacharacters, bermakna watak itu mesti diambil secara literal. Sebagai contoh, /^/ mewakili permulaan baris, manakala /\^/ hanya sepadan dengan aksara ^. /\\/ sepadan dengan garis miring ke belakang \.
^ Padan dengan permulaan baris (rujuk pengubah suai).
$ Padan dengan penghujung baris (rujuk pengubah suai).
. Memadankan mana-mana aksara kecuali pemisah baris (rujuk pengubah suai).
* Padanan mengulang aksara sebelumnya sifar atau lebih kali.
+ Padanan mengulang aksara sebelumnya satu kali atau lebih.
? Padanan mengulang aksara sebelumnya sifar atau satu masa.
(corak) Memadankan rentetan corak Dan .
x| y patuh x atau y.
{ n} n nombor bukan negatif. Padan betul-betul n kejadian watak sebelumnya.
{ n,} n nombor bukan negatif. patuh n atau lebih banyak kejadian watak sebelumnya. /x(1,)/ bersamaan dengan /x+/. /x(0,)/ bersamaan dengan /x*/.
{ n, m} n Dan m nombor bukan negatif. Mematuhi tidak kurang daripada n dan tidak lebih daripada m kejadian watak sebelumnya. /x(0,1)/ bersamaan dengan /x?/.
[ xyz] Memadankan mana-mana aksara yang disertakan dalam kurungan segi empat sama.
[^ xyz] Padan dengan mana-mana aksara kecuali yang disertakan dalam kurungan segi empat sama.
[ a- z] Memadankan mana-mana aksara dalam julat yang ditentukan.
[^ a- z] Padan dengan mana-mana aksara kecuali dalam julat yang ditentukan.
\a Sepadan dengan simbol loceng (BEL).
\A Hanya sepadan dengan permulaan baris, walaupun dengan pengubah suai.
\b Memadankan sempadan perkataan, iaitu kedudukan antara \w Dan \W dalam sebarang susunan.
\B Memadankan mana-mana kedudukan selain daripada sempadan perkataan.
\DenganX Sepadan dengan aksara Ctrl+ X. Contohnya, /\cI/ bersamaan dengan /\t/.
\C Sepadan dengan satu bait, walaupun dengan arahan penggunaan utf8.
\d Sesuai dengan angka tersebut. Bersamaan.
\D Padan dengan aksara bukan angka. Bersamaan dengan [^0-9].
\e Sepadan dengan watak melarikan diri (ESC).
\E Berakhirnya transformasi \L, \Q, \U.
\f Sepadan dengan aksara terjemahan format (FF).
\G Memadankan kedudukan dalam rentetan yang sama dengan pos() .
\l Menukar aksara seterusnya kepada huruf kecil.
\L Menukar aksara kepada huruf kecil sehingga \E.
\n Memadankan pemisah baris.
\pharta benda Padan dengan aksara Unicode yang mempunyai sifat harta benda. Jika harta benda \p(harta benda} .
\Pharta benda Padan dengan aksara Unicode yang tidak mempunyai sifat harta benda. Jika harta benda ditentukan oleh beberapa aksara, gunakan sintaks \P(harta benda} .
\Q Menambah aksara "\" sebelum aksara meta sehingga \E.
\r Sepadan dengan watak carriage return (CR).
\s Padan dengan watak ruang. Bersamaan dengan /[ \f\n\r\t]/.
\S Padan dengan mana-mana aksara bukan ruang putih. Bersamaan dengan /[^ \f\n\r\t]/.
\t Padan dengan aksara tab (HT).
\u Menukar aksara seterusnya kepada huruf besar.
\U Menukar aksara kepada huruf besar sehingga \E.
\w Padan dengan huruf Latin, nombor atau garis bawah. Bersamaan dengan / /.
\W Memadankan mana-mana aksara selain daripada huruf, nombor atau garis bawah. Bersamaan dengan /[^A-Za-z0-9_] /.
\X Padan dengan urutan aksara Unikod daripada simbol utama dan satu set diakritik. Bersamaan dengan /C<(?:\PM\pM*)>/.
\z Hanya sepadan dengan penghujung baris, walaupun dengan pengubah suai.
\Z Memadankan hanya penghujung baris atau pemisah baris pada penghujung baris, walaupun dengan pengubah suai.
\ n n nombor positif. patuh. Jika terdapat kurang kurungan kiri sebelum aksara ini daripada n, Dan n> 9, kemudian bersamaan dengan \0 n.
\0 n n — nombor oktal, tidak lebih daripada 377. Sepadan dengan aksara dengan kod perlapanan n. Contohnya, /\011/ bersamaan dengan /\t/.
\xn n nombor perenambelasan yang terdiri daripada dua digit. Memadankan aksara dengan kod perenambelasan n. Contohnya, /\x31/ bersamaan dengan /1/.
\x(n} n nombor perenambelasan yang terdiri daripada empat digit. Memadankan aksara Unicode dengan kod perenambelasan n. Contohnya, /\x(2663)/ bersamaan dengan /♣/.

6.4.2. Pengubah suai

Operasi ungkapan biasa yang berbeza menggunakan pengubah suai yang berbeza untuk menentukan operasi yang sedang dijalankan. Walau bagaimanapun, empat pengubah suai mempunyai tujuan umum.

Abaikan huruf besar apabila memadankan corak. Apabila menggunakan arahan penggunaan setempat, aksara ditukar kepada kes yang sama berdasarkan tetapan setempat. Memperlakukan rentetan sumber sebagai penimbal berbilang baris teks yang dipisahkan oleh pemisah baris. Ini bermakna metakarakter ^ Dan $ sepadan bukan sahaja dengan permulaan dan penghujung keseluruhan baris, tetapi juga dengan permulaan dan penghujung baris teks yang dibatasi oleh pemisah baris. Memperlakukan rentetan sumber sebagai satu baris teks, mengabaikan pemisah baris. Ini bermakna bahawa metacharacter . sepadan dengan mana-mana watak, termasuk pemisah baris. Membenarkan ruang dan ulasan. Ruang tanpa aksara sebelumnya \ dan tidak disertakan diabaikan. Simbol # memulakan ulasan, yang juga diabaikan.

6.4.3. Kelas aksara Unicode dan POSIX

Kita boleh menggunakan sintaks dalam ungkapan biasa

[:kelas:]

di mana kelas menentukan nama kelas aksara POSIX, iaitu standard mudah alih untuk bahasa C. Apabila menggunakan arahan penggunaan utf8, bukannya kelas POSIX, anda boleh menggunakan kelas aksara Unicode dalam binaan

\p(kelas)

Jadual berikut meringkaskan semua kelas aksara POSIX, kelas aksara Unicode yang sepadan dan aksara meta, jika ada.

Jadual 6.10. Kelas watak
POSIX Unicode Metacharacter Penerangan
alfa IsAlpha surat
alnum IsAlnum Huruf dan nombor
ascii IsAscii aksara ASCII
cntrl IsCntrl Kawalan aksara
digit IsDigit \d Nombor
graf IsGraph Huruf, nombor dan tanda baca
lebih rendah IsLower Huruf kecil
cetak IsPrint Huruf, nombor, tanda baca dan ruang
tebuk IsPunct Tanda baca
angkasa lepas IsSpace \s Watak angkasa
atas IsUpper Huruf besar
perkataan IsWord \w Huruf, nombor dan garis bawah
xdigit IsXDigit Digit heksadesimal

Sebagai contoh, nombor perpuluhan boleh ditetapkan dalam mana-mana tiga cara berikut:

/\d+/ /[:digit:]+/ /\p(IsDigit)+/ # gunakan utf8

Untuk menunjukkan bahawa simbol tidak tergolong dalam kelas tertentu, binaan digunakan

[:^class:] \P(class)

Sebagai contoh, ungkapan berikut mempunyai makna yang sama:

[:^digit:] \D \P(IsDigit) [:^space:] \S \P(IsSpace) [:^word:] \W \P(IsWord)

6.4.4. Mengingati subrentetan

Menggunakan kurungan dalam ungkapan biasa menyebabkan subrentetan yang sepadan dengan corak dalam kurungan disimpan dalam penampan khas. Untuk mengakses n Substring yang disimpan ke dalam ungkapan biasa menggunakan pembinaan \ n, dan di luarnya $ n, Di mana n boleh mengambil sebarang nilai bermula dari 1. Walau bagaimanapun, perlu diingat bahawa PERL menggunakan ungkapan \10 , \11 , dsb. sebagai sinonim untuk kod aksara oktal \010 , \011 , dsb. Kekaburan di sini diselesaikan seperti berikut. Aksara \10 dianggap merujuk kepada subrentetan ke-10 yang diingati jika ia didahului oleh sekurang-kurangnya sepuluh kurungan kiri dalam ungkapan biasa; jika tidak, ia ialah aksara dengan kod perlapanan 10. Metakarakter \1 , \9 sentiasa dianggap sebagai rujukan kepada subrentetan yang disimpan. Contoh:

Jika (/(.)\1/) ( # cari cetakan aksara berulang pertama ""$1" ialah aksara ulangan pertama\n"; ) jika (/Masa: (..):(..):(. .)/ ) ( # komponen masa ekstrak $jam = $1; $minit = $2; $saat = $3; )

Sebagai tambahan kepada $1 , $2 , pembolehubah, terdapat beberapa lagi pembolehubah khas yang menyimpan hasil operasi terakhir dengan ungkapan biasa, iaitu:

Berikut ialah contoh:

"AAA111BBB222"=~/(\d+)/; cetak "$`\n"; # Cetakan AAA "$&\n"; # 111 cetakan "$"\n"; # BBB222 cetakan "$+\n"; # 111

Semua pembolehubah khas ini mengekalkan nilainya sehingga akhir blok yang disertakan atau sehingga padanan corak yang berjaya seterusnya.

6.4.5. Sampel Lanjutan

PERL mengandungi beberapa binaan tambahan yang boleh digunakan dalam ungkapan biasa untuk meningkatkan keupayaannya. Semua binaan ini disertakan dalam kurungan dan bermula dengan simbol? , yang membezakan mereka daripada menghafal subrentetan.

(?#teks) Satu komen. Keseluruhan struktur diabaikan. (?pengubahsuai-pengubahsuai) Mendayakan atau melumpuhkan yang ditentukan. Pengubah suai sebelum simbol - dihidupkan, dan yang selepas simbol dimatikan. Contoh:

Jika (/aaa/) ( ) # padanan sensitif huruf besar/kecil jika (/(?i)aaa/) ( ) # padanan tidak sensitif huruf besar/kecil

(?:corak) (?pengubahsuai-pengubahsuai:corak) Membolehkan anda mengumpulkan subungkapan bagi ungkapan biasa tanpa mengingati padanan yang ditemui. Borang kedua juga membolehkan atau melumpuhkan . Sebagai contoh, ungkapan /ko(?:t|shka)/ ialah versi pendek bagi ungkapan /cat|cat/. (?=corak) Padan dengan melihat ke hadapan tanpa mengingati perlawanan yang ditemui. Contohnya, /Windows (?=95|98|NT|2000)/ sepadan dengan "Windows" dalam rentetan "Windows 98" tetapi tidak sepadan dalam rentetan "Windows 3.1". Selepas padanan, pencarian diteruskan dari kedudukan di sebelah perlawanan yang ditemui, tanpa melihat ke hadapan. (?!corak) Ketidakkonsistenan dengan melihat ke hadapan tanpa mengingati perlawanan yang ditemui. Contohnya, /Windows (?!95|98|NT|2000)/ sepadan dengan "Windows" dalam rentetan "Windows 3.1" tetapi tidak sepadan dalam rentetan "Windows 98". Selepas padanan, pencarian diteruskan dari kedudukan di sebelah perlawanan yang ditemui, tanpa melihat ke hadapan. (?<=corak) Padan dengan menoleh ke belakang tanpa mengingati padanan yang ditemui. Sebagai contoh, ungkapan /(?<=\t)\w+/ соответствует слову, следующему за символом табуляции, и символ табуляции не включается в $& . Фрагмент, соответствующий заглядыванию назад, должен иметь фиксированную ширину. (?corak
) Ketidakkonsistenan dengan melihat ke belakang tanpa mengingati perlawanan yang ditemui. Sebagai contoh, ungkapan /(?6.4.6. Operasi dengan ungkapan biasa

Setakat ini kami telah menyertakan ungkapan biasa dalam aksara //. Malah, aksara pembatas bagi ungkapan biasa ditentukan oleh operasi q yang kami gunakan padanya. Bahagian ini menerangkan secara terperinci semua operasi bahasa PERL dengan ungkapan biasa.

6.4.6.1. Padanan corak

Sintaks: /corak/pengubahsuai m/ corak/pengubahsuai

corak dan mengembalikan benar atau salah bergantung pada keputusan perlawanan. Rentetan yang hendak dipadankan diberikan oleh operan kiri operasi =~ atau !~, sebagai contoh:

$mynumber = "12345"; if ($mynumber =~ /^\d+$/) ( # jika rentetan $mynumber terdiri daripada digit perpuluhan, Itu ... )

Jika rentetan tidak dinyatakan, maka kandungan pembolehubah khas $_ dibandingkan. Khususnya, contoh sebelumnya boleh ditulis semula seperti berikut:

$_ = "12345"; jika (/^\d+$/) ( ... )

Jika ungkapan biasa disertakan dalam // , maka m terkemuka adalah pilihan. Pembinaan m terkemuka membolehkan anda menggunakan mana-mana aksara yang dibenarkan dalam operasi q sebagai pembatas ungkapan biasa. Kes khas yang berguna:

Jika corak

Jika tiada pengubahsuai dinyatakan g dan keputusan perlawanan diberikan kepada senarai, maka jika perlawanan gagal, senarai kosong dikembalikan. Keputusan perlawanan yang berjaya bergantung pada kehadiran tanda kurung dalam corak. Jika tiada, maka senarai (1) dikembalikan. Jika tidak, senarai dikembalikan yang terdiri daripada nilai pembolehubah $1, $2, dsb., iaitu senarai semua subrentetan yang diingati. Contoh seterusnya

($w1, $w2, $rehat) = ($x =~ /^(\S+)\s+(\S+)\s*(.*)/);

meletakkan perkataan pertama rentetan $x ke dalam pembolehubah $w1, perkataan kedua ke dalam pembolehubah $w2, dan selebihnya rentetan ini ke dalam pembolehubah $rest.

Pengubah suai g menghidupkan mod padanan corak global, iaitu, mencari semua padanan dalam rentetan. Tingkah lakunya bergantung pada konteks. Jika keputusan padanan diberikan kepada senarai, maka senarai semua subrentetan yang diingati dikembalikan. Jika corak tidak mengandungi kurungan, maka senarai semua padanan dengan corak itu dikembalikan seolah-olah ia disertakan sepenuhnya dalam kurungan. Contoh seterusnya

$_ = "12:23:45"; @hasil = /\d+/g; foreach $elem (@result) ( print "$elem\n"; )

akan memaparkan baris 12, 23 dan 45.

DALAM konteks skalar padanan pengubah suai g setiap kali ia mencari padanan corak seterusnya dan mengembalikan benar atau salah bergantung pada hasil carian. Kedudukan dalam rentetan selepas perlawanan terakhir boleh dibaca atau diubah oleh fungsi pos(). Carian yang gagal biasanya akan menetapkan semula kedudukan carian kepada sifar, tetapi kita boleh mengelakkannya dengan menambahkan pengubah suai c. Menukar rentetan juga menetapkan semula kedudukan carian dalam rentetan itu.

Ciri-ciri tambahan menyediakan \G metacharacter, yang hanya bermakna apabila digabungkan dengan pengubah suai g. Metacharacter ini sepadan dengan kedudukan carian semasa dalam rentetan. Menggunakan pembinaan m/\G/gc adalah mudah, khususnya, untuk menulis penganalisis leksikal yang berprestasi pelbagai tindakan untuk leksem yang ditemui dalam teks yang dianalisis. Contoh seterusnya

$_ = "Word1, word2, dan 12345."; LOOP: ( print("nombor "), buat semula LOOP jika /\G\d+\b[,.;]?\s*/gc; print("word "), buat semula LOOP jika /\G+\b[,. ;]?\s*/gc; print("tidak diketahui "), buat semula LOOP jika /\G[^A-Za-z0-9]+/gc; )

akan dipaparkan rentetan perkataan perkataan perkataan bilangan.

6.4.6.2. Padanan corak tunggal

Sintaks: ?corak? m? corak?

Reka bentuk ini sama sekali dengan m/ corak/ dengan satu-satunya perbezaan: padanan corak yang berjaya berlaku hanya sekali antara panggilan untuk menetapkan semula() . Ini berguna, sebagai contoh, apabila kita perlu mencari hanya kejadian pertama corak dalam setiap fail daripada set yang kita lihat, sebagai contoh:

sementara(<>) ( jika (?^$?) ( ... # proses baris kosong pertama fail ) ) teruskan ( set semula jika eof; # set semula status ?? untuk fail seterusnya }

6.4.6.3. Mencipta Ekspresi Biasa

Sintaks:qr/ tali/pengubahsuai

Konstruk ini mencipta ungkapan biasa dengan teks tali dan pengubahsuai pengubahsuai dan menyusunnya. Jika pembatas ialah aksara "", maka interpolasi rentetan tali o

Setelah dibuat, ungkapan biasa boleh digunakan sama ada secara bebas atau sebagai serpihan ungkapan biasa yang lain. Contoh:

$re = qr/\d+/; $string =~ /\s*$(re)\s*/; # kemasukan dalam ungkapan biasa lain $string =~ $re; # penggunaan tersuai $string =~ /$re/; # perkara yang sama $re = qr/$header/is; s/$re/text/; # sama seperti s/$header/text/is

6.4.6.4. Penggantian

Sintaks:s/ corak/tali/pengubahsuai

Operasi ini memadankan rentetan yang diberikan dengan corak corak dan menggantikan serpihan yang ditemui dengan rentetan tali. Ia mengembalikan bilangan penggantian yang dibuat, atau palsu (lebih tepat, rentetan kosong) jika perlawanan gagal. Rentetan yang hendak dipadankan ditentukan oleh operan kiri operasi =~ atau !~. Ia mestilah pembolehubah skalar, elemen tatasusunan atau elemen tatasusunan bersekutu, Sebagai contoh:

$path = "/usr/bin/perl"; $path =~ s|/usr/bin|/usr/local/bin|;

$_ = "/usr/bin/perl"; s|/usr/bin|/usr/local/bin|;

Sebagai tambahan kepada yang standard, pengubah berikut boleh digunakan di sini:

corak tali mesti mempunyai pasangan pembatas sendiri, seperti s(foo) atau s /bar/ .

Jika pembatas ialah aksara "", maka interpolasi rentetan corak tidak dihasilkan. Dalam kes lain, sampel diinterpolasi dan jika ia mengandungi pembolehubah, maka ia disusun untuk setiap perbandingan. Untuk mengelakkan ini, gunakan pengubah suai o(sudah tentu, jika anda pasti bahawa nilai pembolehubah yang disertakan dalam sampel kekal tidak berubah).

Jika corak ialah baris kosong, maka ungkapan biasa yang terakhir berjaya dipadankan digunakan sebaliknya.

Secara lalai, hanya sampel pertama yang ditemui diganti. Untuk menggantikan semua kemunculan corak dalam rentetan, anda perlu menggunakan pengubah suai g.

Pengubah suai e menunjukkan bahawa tali adalah ungkapan. Dalam kes ini, untuk tali Fungsi eval() digunakan dahulu dan kemudian penggantian dilakukan. Contoh:

$_ = "123"; s/\d+/$&*2/e; # $_ = "246" s/\d/$&*2/cth; # sama

Mari kita berikan beberapa lagi contoh tipikal menggunakan operasi gantian. Mengalih keluar ulasan seperti /**/ daripada teks program Java atau C:

$program =~ s ( /\* # Mula ulasan.*? # Bilangan minimum aksara \*/ # Tamat ulasan )gsx;

Mengalih keluar awal dan ruang belakang dalam baris $var:

Untuk ($var) ( s/^\s+//; s/\s+$//; )

Menyusun semula dua medan pertama dalam $_ . Ambil perhatian bahawa rentetan gantian menggunakan pembolehubah $1 dan $2 dan bukannya metacharacters \1 dan \2:

S/([^ ]*) *([^ ]*)/$2 $1/;

Menggantikan tab dengan ruang yang sejajar dengan lajur yang boleh dibahagikan dengan lapan:

1 manakala s/\t+/" " x (panjang($&)*8 - panjang($`)%8)/e;

6.4.6.5. Alih huruf

Sintaks:tr/ senarai1/senarai2/pengubahsuai y/ senarai1/senarai2/pengubahsuai

Alih huruf terdiri daripada menggantikan semua aksara daripada senarai senarai1 memadankan aksara daripada senarai senarai2. Ia mengembalikan bilangan aksara yang diganti atau dialih keluar. Senarai mesti terdiri daripada aksara individu dan/atau julat dalam bentuk a-z . Rentetan yang hendak ditukar ditentukan oleh operan kiri operasi =~ or!~. Ia mestilah pembolehubah skalar, elemen tatasusunan atau elemen tatasusunan bersekutu, sebagai contoh:

$test = "ABCDEabcde"; $ujian =~ tr/A-Z/a-z/; # penggantian huruf kecil kepada ibu kota

Jika rentetan tidak ditentukan, maka operasi penggantian dilakukan pada pembolehubah khas $_. Khususnya, contoh sebelumnya boleh ditulis semula seperti berikut:

$_ = "ABCDEabcde"; tr/A-Z/a-z/;

Kita boleh menggunakan sebarang simbol yang dibenarkan dalam operasi q dan bukannya //. Jika senarai1 disertakan dalam kurungan berpasangan, kemudian senarai2 mesti mempunyai pasangan pembatas sendiri, seperti tr(A-Z) atau tr /a-z/.

Operasi ini biasanya dipanggil tr. Sinonim y diperkenalkan untuk fanatik editor sed dan hanya digunakan oleh mereka. Alih huruf menyokong pengubah suai berikut:

Pengubah suai c menyebabkan semua aksara yang tiada dalam senarai dialih huruf senarai1. Contohnya, operasi tr/a-zA-Z/ /c akan menggantikan semua aksara bukan Latin dengan ruang.

Secara lalai jika senarai2 lebih pendek daripada senarai1, ia dilengkapkan dengan simbol terakhirnya, dan jika ia kosong, ia diambil sama dengan senarai1(ini mudah untuk mengira bilangan aksara kelas tertentu dalam satu baris). Pengubah suai d mengubah peraturan ini: semua aksara daripada senarai1, yang tidak mempunyai surat-menyurat dalam senarai2, dialih keluar daripada baris. Sebagai contoh, operasi tr/a-zA-Z//cd akan mengalih keluar semua aksara bukan huruf daripada rentetan.

Pengubah suai s mengalih keluar ulangan: jika beberapa aksara dalam satu baris digantikan dengan aksara yang sama, maka hanya satu contoh aksara ini akan ditinggalkan. Contohnya, operasi tr/ / /s mengalih keluar ruang berulang daripada rentetan.

Pengubah suai C Dan U direka untuk menukar aksara daripada pengekodan sistem kepada UTF-8 dan sebaliknya. Yang pertama menunjukkan pengekodan sumber, dan yang kedua menunjukkan pengekodan hasil. Contohnya, tr/\0-\xFF//CU akan menukar rentetan daripada pengekodan sistem kepada UTF-8 dan tr/\0-\xFF//UC akan melakukan penukaran terbalik.

Transliterasi dilakukan tanpa menginterpolasi senarai aksara, jadi untuk menggunakan pembolehubah di dalamnya anda perlu memanggil fungsi eval(), sebagai contoh.

> Ungkapan biasa dalam Perl

Ungkapan biasa digunakan untuk mencari corak dalam rentetan. Contohnya, untuk mencari nama tertentu dalam buku telefon, atau, sebagai contoh, semua nama bermula dengan huruf "a". Bekerja dengan ungkapan biasa adalah salah satu yang paling berkuasa dan berguna, dan pada masa yang sama yang paling sukar untuk difahami. Ciri Perl. Kami berharap selepas membaca artikel ini anda akan memahami betapa berkuasa dan alat yang berguna. Setelah mendapat sedikit pengalaman, anda akan dapat menggunakan peluang ini untuk faedah yang besar anda.

Operator

Perl menggunakan tiga operator untuk bekerja dengan ungkapan biasa:
- operator perbandingan (padanan - m//), operator penggantian
(penggantian s///) dan operator terjemahan (terjemahan - tr///).

Ketiga-tiga pengendali menggunakan pembolehubah $_ secara lalai, jadi
selanjutnya, sehingga operasi =~ dan!~ dibentangkan, kami akan
gunakannya.

Operator perbandingan menyemak sama ada ungkapan yang diuji sepadan
corak, dan mengembalikan nilai 1 jika ada, dan nilai 0 in
sebaliknya. Notasi operator ini terdiri daripada huruf m,
pemisah (selalunya ini adalah garis miring - /, tetapi pada dasarnya ia boleh
menjadi hampir mana-mana watak), corak dan pembatas lain (sama
seperti yang pertama :).

Operator perbandingan
$_ = ;
jika (m/hello/) (
cetak "hello pengguna\n";
}

if ($input("siteurl") =~ #http://#) (
print $input("siteurl");
}

Contoh ini menyemak sama ada rentetan dikembalikan daripada
input standard, perkataan "hello". Jika ya (pengendali m// akan kembali
nilai 1), maka frasa "hello pengguna" akan dikembalikan kepada output standard.

Nota: Sebenarnya aksara "m" adalah pilihan, jadi
Pernyataan dalam contoh ini mungkin kelihatan seperti /hello/.

Pengendali penggantian mencari semua subrentetan dalam rentetan yang memuaskan
corak, dan menggantikannya dengan beberapa nilai lain. Rakam ini
operator terdiri daripada huruf s, menunjukkan bahawa ia sebenarnya
pengendali penggantian kedua-dua yang asal (apa yang perlu diganti) dan pengendali penggantian (untuk
apa yang perlu diganti) templat dipisahkan oleh pembatas.

Pengendali penggantian
$_ = "Nama saya Fred";
# oh tidak, nama saya Jonathan!
s/Fred/Jonathan/;

Dalam contoh ini, dalam baris $_, semua perkataan Fred akan ditukar kepada Jonathan.

Operator terjemahan juga melakukan penggantian, tetapi dengan cara yang sedikit berbeza
watak - ia digunakan untuk menggantikan simbol individu beberapa
simbol lain (khusus). Sintaks pengendali ini adalah serupa dengan
sintaks pengendali penggantian, dengan perbezaan yang pertama
jelas bermula dengan huruf tr, dan antara pembatas tidak ada
templat, dan kumpulan simbol, yang pertama - simbol asal, yang kedua -
kad bebas, dan aksara yang sepadan mesti muncul pada
kedudukan yang sama dalam kumpulan mereka - jika anda ingin menggantikan,
sebagai contoh, Latin "m" kepada Cyrillic "m", mereka harus berdiri di atasnya
tempat yang sama: "m" - dalam kumpulan pertama aksara, "m" - dalam kedua.

Operator terjemahan
$_ = "hai.there, my.name.is.jonathan,";
tr/.,/ !/;

Dalam contoh ini, semua koma akan ditukar kepada tanda seru, A
titik ke ruang.

Pengubah suai

Keupayaan setiap operator ini boleh dikembangkan menggunakan
pengubahsuai. Pengubah suai, secara kasarnya, melambangkan itu
dilampirkan pada operator (contohnya, seperti ini - s/fred/Jonathan/i), bercakap tentang
bagaimana dia perlu menghuraikan nilai kerja.

Pengubah suai untuk pengendali perbandingan:

  • x - membolehkan anda menggunakan ungkapan biasa lanjutan;

Pengubah suai untuk pengendali penggantian:

  • e - menilai ungkapan penggantian sebelum penggantian;
  • g - mencari semua subrentetan yang ditemui;
  • i - mengabaikan kes aksara dalam rentetan;
  • m - merawat rentetan sebagai nilai berbilang baris;
  • s - merawat rentetan sebagai nilai satu baris;
  • x - membolehkan anda menggunakan ungkapan biasa lanjutan.

Pengubah suai

$_ = "Nama saya Fred";
s/fred/Jonathan/i; # Nama saya Jonathan
s/jonathan/rutin()/iaitu; # Nama saya ialah

Operasi =~ dan!~

Operator =~ dan!~ membenarkan penggunaan dengan m//, s/// dan
tr /// sebarang pembolehubah, bukan hanya $_, yang digunakan oleh ini
pengendali lalai.

Operator =~ menjalankan fungsi yang sama seperti operator tugasan "="
(jika digunakan dengan operator s/// dan tr///) dan operator
perbandingan "eq" (apabila digunakan dengan operator m//).

Operasi =~
$name = "nama saya Fred";
$name =~ s/fred/Jonathan/ig;

$string = "hello world";
jika ($ rentetan =~ /hello/i) (
cetak "helloworlded dalam rentetan ini.";
}

Begitu juga, operator!~ digunakan dengan cara yang sama seperti operator "ne" (its
ejaan adalah serupa dengan operasi perbandingan berangka!=), digunakan
hanya dengan pengendali perbandingan dan bermakna penolakan kepuasan
templat.

Operasi!~
$string = "baik";
jika ($string !~ /bad/) (
cetak "hey, ia belum terlalu teruk!";
}

Ingatan

Dan akhirnya - tentang peluang untuk bekerja dengan hasilnya dengan lebih mudah
memproses ungkapan biasa, iaitu menyimpannya secara berasingan
pembolehubah. Pembolehubah tersebut ialah $&, $`, $", dan
set pembolehubah $1, $2, ..., $9.

$& pembolehubah

Pembolehubah ini bertujuan untuk menyimpan serpihan rentetan yang
berpuas hati dengan corak yang ditentukan oleh ungkapan biasa. Ia mudah di
kes seperti, sebagai contoh, jika anda perlu mencari nombor dalam rentetan, tetapi
Tidak diketahui apakah nombor ini. Inilah yang mungkin kelihatan seperti:

$string = "ralat 404."
$string =~ m/\d+/;

Pembolehubah $` dan $"

Pembolehubah ini digunakan untuk menyimpan serpihan yang tidak
berpuas hati dengan corak, iaitu substrings yang datang sebelum dan selepas
hasil dengan sewajarnya. Dalam erti kata lain, selepas pembedahan, cth.
perbandingan, nilai rentetan asal dibahagikan kepada tiga bahagian - bahagian,
yang sesuai dengan templat, dan serpihan yang terdapat di hadapannya dan
selepas dia. Bahagian ini diletakkan dalam pembolehubah $&, $` dan $"
masing-masing. (Perhatikan bahawa dalam pembolehubah pertama -
petikan belakang, dan dalam kedua - hadapan). Mari lihat yang sebelumnya
contoh.

$string = "ralat 404."
$string =~ m/\d+/;

$nombor = $&; # $number mengandungi "404"
$sebelum = $`; # $before mengandungi "ralat"
$after = $"; # $after mengandungi "."

Pembolehubah $1..$9

Pembolehubah ini digunakan untuk menyimpan serpihan rentetan yang
berpuas hati dengan serpihan khusus templat yang sepadan. DALAM
dalam templat, serpihan diserlahkan menggunakan kurungan. Setiap serpihan
nombor itu diserlahkan mengikut susunan di mana ia berada, dan
pembolehubah yang sepadan akan mengandungi nilainya.

$string = "ini adalah huruf besar";
$string =~ s/(atas\w+)/uc($1)/;
# $string = "ini perlu HURUF BESAR"

$string = "15 biji epal, 2 foos, 3 bar";
manakala ($rentetan =~ m/(\d+) (\w+)/g) (
cetak "$2: $1\n";
}
# Mencetak epal: 15
# foos: 2
# bar: 3

Nikolay Matkovsky,
11.05.2006.