Menghilangkan garis miring ke depan dalam ekspresi reguler
106
Pertanyaan saya sederhana, dan ini tentang pelarian ekspresi reguler. Apakah Anda harus menghindari garis miring /dalam ekspresi reguler? Dan bagaimana Anda akan melakukannya?
Penerapan bahasa / ekspresi reguler apa yang Anda gunakan?
Gumbo
Yang cukup menarik, saya sedang mencari pertanyaan ini untuk Javascript. Tapi kemudian IDE saya mengatakan saya menggunakan pelarian yang tidak perlu. Begitu myStr.replace(/[/:.-]+/gi, '_')juga mengejutkan saya. Saya pikir saya akan membutuhkan /[\/:.-]+/gi. Saya tidak dapat memutuskan apakah ini keren atau membingungkan.
Turbo
Jawaban:
90
Konteks / bahasa apa? Beberapa bahasa digunakan /sebagai pembatas pola, jadi ya, Anda perlu menghindarinya, bergantung pada bahasa / konteks mana. Anda dapat menghindarinya dengan meletakkan garis miring ke belakang di depannya: \/Untuk beberapa bahasa (seperti PHP) Anda dapat menggunakan karakter lain sebagai pembatas dan oleh karena itu Anda tidak perlu menghindarinya. Tapi AFAIK dalam semua bahasa, satu-satunya makna khusus yang /dimilikinya adalah mungkin pemisah pola yang ditentukan.
Di Perl, Anda dapat memilih pembatas alternatif. Anda tidak terbatas pada m//. Anda bisa memilih yang lain, seperti m{}. Maka melarikan diri tidak perlu. Faktanya, Damian Conway dalam "Perl Best Practices" menegaskan bahwa itu m{}adalah satu-satunya pembatas alternatif yang harus digunakan, dan ini diperkuat oleh Perl :: Critic (di CPAN). Meskipun Anda bisa lolos dengan menggunakan berbagai karakter pembatas alternatif, //dan {}tampaknya yang paling jelas untuk diuraikan nanti. Namun, jika salah satu dari pilihan tersebut mengakibatkan terlalu banyak pelarian, pilih mana yang paling cocok untuk keterbacaan. Contoh umum adalah m(...), m[...], danm!...! .
Dalam kasus di mana Anda tidak dapat atau memilih untuk tidak menggunakan pembatas alternatif, Anda dapat menghindari garis miring ke depan dengan garis miring terbalik: m/\/[^/]+$/misalnya (menggunakan pembatas alternatif yang bisa menjadi m{/[^/]+$}, yang mungkin terbaca lebih jelas). Meloloskan diri dari garis miring dengan garis miring terbalik cukup umum untuk mendapatkan nama dan laman wikipedia: Sindrom Tusuk Gigi Miring . Dalam ekspresi reguler di mana hanya ada satu contoh, meloloskan diri dari garis miring mungkin tidak dianggap sebagai penghalang keterbacaan, tetapi jika itu mulai lepas kendali, dan jika bahasa Anda mengizinkan pembatas alternatif seperti Perl, itu akan menjadi solusi pilihan.
Bisakah Anda memberi contoh? Saya memiliki ini: perl -pi -e "s/chdir .*/chdir $ROBOT_PATH/g" startup_scripts/supervisord.confDan saya mengalami konflik dengan garis miring ke depan.
CMCDragonkai
Perhatikan bahwa Anda menggunakan s, bukan an m, saat melakukan penggantian (alias substitusi) dengan ekspresi reguler. perlfect.com/articles/regex.shtml
Mashmagar
2
@CMCDragonkai perl -pi -e "s{chdir .*}{chdir $ROBOT_PATH}g" startup_scripts/supervisord.conf... tapi ini mungkin lebih baik: perl -pi -e 's/chdir .*/chdir $ENV{ROBOT_PATH}/g' startup_scripts/supervisord.confkarena menghindari interpolasi shell.
DavidO
1
Alternatif untuk meng-escape /karakter literal adalah dengan menggunakan fungsionalitas regex untuk menentukan karakter dengan pengkodean ASCII-nya, dalam hex atau oktal. Perl menerima bentuk oktal \57(sumber regular-expressions.info/refcharacters.html )
lukeuser
Di halaman yang ditautkan oleh Lukeuser (terima kasih) juga ada Escape Sequence \ Q ... \ E. Ini berhasil untuk saya.
pengguna3012857
11
Gunakan garis miring terbalik \atau memilih pembatas yang berbeda, yaitu m#.\d#bukan /.\d/
"Di Perl, Anda dapat mengubah / reguler ekspresi pembatas untuk hampir semua karakter khusus lain jika Anda mendahului dengan huruf m (untuk pertandingan);"
myStr.replace(/[/:.-]+/gi, '_')
juga mengejutkan saya. Saya pikir saya akan membutuhkan/[\/:.-]+/gi
. Saya tidak dapat memutuskan apakah ini keren atau membingungkan.Jawaban:
Konteks / bahasa apa? Beberapa bahasa digunakan
/
sebagai pembatas pola, jadi ya, Anda perlu menghindarinya, bergantung pada bahasa / konteks mana. Anda dapat menghindarinya dengan meletakkan garis miring ke belakang di depannya:\/
Untuk beberapa bahasa (seperti PHP) Anda dapat menggunakan karakter lain sebagai pembatas dan oleh karena itu Anda tidak perlu menghindarinya. Tapi AFAIK dalam semua bahasa, satu-satunya makna khusus yang/
dimilikinya adalah mungkin pemisah pola yang ditentukan.sumber
Berikut beberapa opsinya:
Di Perl, Anda dapat memilih pembatas alternatif. Anda tidak terbatas pada
m//
. Anda bisa memilih yang lain, sepertim{}
. Maka melarikan diri tidak perlu. Faktanya, Damian Conway dalam "Perl Best Practices" menegaskan bahwa itum{}
adalah satu-satunya pembatas alternatif yang harus digunakan, dan ini diperkuat oleh Perl :: Critic (di CPAN). Meskipun Anda bisa lolos dengan menggunakan berbagai karakter pembatas alternatif,//
dan{}
tampaknya yang paling jelas untuk diuraikan nanti. Namun, jika salah satu dari pilihan tersebut mengakibatkan terlalu banyak pelarian, pilih mana yang paling cocok untuk keterbacaan. Contoh umum adalahm(...)
,m[...]
, danm!...!
.Dalam kasus di mana Anda tidak dapat atau memilih untuk tidak menggunakan pembatas alternatif, Anda dapat menghindari garis miring ke depan dengan garis miring terbalik:
m/\/[^/]+$/
misalnya (menggunakan pembatas alternatif yang bisa menjadim{/[^/]+$}
, yang mungkin terbaca lebih jelas). Meloloskan diri dari garis miring dengan garis miring terbalik cukup umum untuk mendapatkan nama dan laman wikipedia: Sindrom Tusuk Gigi Miring . Dalam ekspresi reguler di mana hanya ada satu contoh, meloloskan diri dari garis miring mungkin tidak dianggap sebagai penghalang keterbacaan, tetapi jika itu mulai lepas kendali, dan jika bahasa Anda mengizinkan pembatas alternatif seperti Perl, itu akan menjadi solusi pilihan.sumber
perl -pi -e "s/chdir .*/chdir $ROBOT_PATH/g" startup_scripts/supervisord.conf
Dan saya mengalami konflik dengan garis miring ke depan.s
, bukan anm
, saat melakukan penggantian (alias substitusi) dengan ekspresi reguler. perlfect.com/articles/regex.shtmlperl -pi -e "s{chdir .*}{chdir $ROBOT_PATH}g" startup_scripts/supervisord.conf
... tapi ini mungkin lebih baik:perl -pi -e 's/chdir .*/chdir $ENV{ROBOT_PATH}/g' startup_scripts/supervisord.conf
karena menghindari interpolasi shell./
karakter literal adalah dengan menggunakan fungsionalitas regex untuk menentukan karakter dengan pengkodean ASCII-nya, dalam hex atau oktal. Perl menerima bentuk oktal\57
(sumber regular-expressions.info/refcharacters.html )Gunakan garis miring terbalik
\
atau memilih pembatas yang berbeda, yaitum#.\d#
bukan/.\d/
"Di Perl, Anda dapat mengubah / reguler ekspresi pembatas untuk hampir semua karakter khusus lain jika Anda mendahului dengan huruf m (untuk pertandingan);"sumber
Jika pembatasnya adalah /, Anda harus keluar.
sumber
Jika Anda menggunakan C #, Anda tidak perlu menghindarinya.
sumber
Untuk java, Anda tidak perlu.
Jika Anda meletakkan \ di depan /. IDE akan memberi tahu Anda "Redundant Character Escape" \ / "di ReGex"
sumber