Apa perbedaan antara $ / dan $ ¢ di regex?


11

Seperti yang ditunjukkan judulnya, apa perbedaan antara $/dan ? Mereka tampaknya selalu memiliki nilai yang sama:

my $text = "Hello world";

$text ~~ /(\w+) { say $/.raku } (\w+)/;
$text ~~ /(\w+) { say $¢.raku } (\w+)/;

Keduanya menghasilkan objek Match dengan nilai yang sama. Apa logika menggunakan satu di atas yang lain?

Jawaban:


11

Variabel $/mengacu pada kecocokan terbaru sedangkan variabel mengacu pada kecocokan terluar terbaru. Di sebagian besar regex dasar seperti di atas, itu mungkin satu dan sama. Tetapi seperti yang dapat dilihat dari output .rakumetode, Matchobjek dapat berisi Matchobjek lain (itulah yang Anda dapatkan ketika Anda menggunakan $<foo>atau $1untuk menangkap).

Misalkan kita memiliki regex berikut dengan tangkapan terukur

/ ab (cd { say $¢.from, " ", $¢.to } ) + /

Dan berlari itu akan melihat output berikut jika kita cocok dengan "abcdcdcd":

0 2
0 4
0 6

Tetapi jika kita berubah dari menggunakan menjadi $/, kita mendapatkan hasil yang berbeda:

2 2
4 4
6 6

(Alasan yang .tokelihatannya agak tidak aktif adalah .pos— dan - tidak diperbarui sampai akhir blok tangkap.)

Dengan kata lain, akan selalu merujuk pada apa yang akan menjadi objek pertandingan terakhir Anda (yaitu, $final = $text ~~ $regex) sehingga Anda dapat melintasi pohon tangkap kompleks di dalam regex persis seperti yang Anda lakukan setelah menyelesaikan pertandingan penuh Jadi dalam contoh di atas, Anda bisa saja lakukan $¢[0]untuk merujuk pada pertandingan pertama, $¢[1]yang kedua, dll.

Di dalam blok kode regex, $/akan merujuk pada kecocokan paling cepat. Dalam kasus di atas, itulah kecocokan untuk di dalam ( )dan tidak akan tahu tentang kecocokan lainnya, atau awal asli pencocokan: hanya awal untuk ( )blok. Jadi berikan regex yang lebih kompleks:

/ a $<foo>=(b $<bar>=(c)+ )+ d /

Kami dapat mengakses di titik mana saja menggunakan $ ¢ semua footoken dengan mengatakan $¢<foo>. Kami dapat mengakses bartoken yang diberikan foodengan menggunakan $¢<foo>[0]<bar>. Jika kami menyisipkan blok kode di dalam footangkapan, ia akan dapat mengakses bartoken dengan menggunakan $<bar>atau $/<bar>, tetapi itu tidak akan dapat mengakses lainnya foo.


1
Ohhh! Saya menafsirkan dokumen "Perbedaan utama antara $/dan ruang lingkup: yang terakhir hanya memiliki nilai di dalam regex" berarti hanya jejak sisa, sama seperti Cursor. Ketika saya membaca jawaban Anda, saya pikir akan $*TOPsaya buat di A kemungkinan perbaikan? bagian dari jawaban saya kepada SO "Mengapa / bagaimana variabel tambahan diperlukan dalam mencocokkan karakter arbiter berulang dengan kelompok tangkapan?". Tetapi upaya saya untuk mengganti $*TOPdengan gagal. Apakah Anda mengerti maksud saya dalam jawaban itu? Bisakah Anda membuatnya bekerja?
raiph

Raiph: Jadi dalam tata bahasa, diperbarui untuk setiap token, jadi Anda harus mengatakannya $*TOP := $¢dalam TOPtoken tetapi itu tidak menghilangkan kebutuhan akan $*TOPvar tentu saja. Saya setuju itu akan luar biasa untuk bisa merujuk pertandingan di tingkat atas. Masalahnya, pada akhirnya, masih yang Anda identifikasi: ketika posisional / hash cocok dengan posting ke objek yang cocok. Saat menggunakan - yang per-token - hasilnya akan melalui pos definisi segera setelah { }blok penutupnya ditemukan.
user0721090601

Yang menarik bagi saya adalah bahwa dalam pengembangan Binex, saya belum merasa lebih buruk secara komputasional untuk mengirim hasil pertandingan segera setelah menjumpai mereka. Pada akhir hari, Anda mendorong / muncul ke daftar cache / hash, atau Anda mendorong / muncul ke daftar / hash Pertandingan. Namun, mungkin ada semacam kecepatan internal yang saya tidak tahu digunakan untuk LTM yang kemungkinan merupakan inti dari itu (yang { }mengakhiri token untuk keperluan LTM, dan lebih mungkin untuk dijalankan / diuji daripada sisa token dalam |pengelompokan)
user0721090601

Ahhh Saya telah melompat ke kesimpulan itu dinamis, dan terkejut ketika itu tidak berhasil. Tetapi uang receh yang sekarang jatuh itu leksikal, seperti yang bisa saya duga ketika Anda menggunakan kata "terluar", dan, seperti yang Anda jelaskan, ditetapkan pada awal setiap aturan.
raiph

Jadi, iiuc, pada awal aturan, objek pencocokan baru dibuat yang mencatat posisi kursor mesin yang cocok dalam string input asli, tetapi sebaliknya kosong. (Benar?) Kemudian dan $/terikat ke objek yang sama, yaitu objek pencocokan baru ini, yang akan mencatat apa yang cocok dan ditangkap oleh aturan ini saat berlangsung. Kemudian, saat pencocokan berlangsung, tetap terikat ke objek pencocokan keseluruhan ini, sedangkan $/rebound setiap kali sebuah objek pencocokan baru dibuat, jadi itu selalu sesuai, seperti yang Anda katakan, dengan objek pencocokan terbaru. Baik?
raiph
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.