Regex: Tentukan "spasi atau awal string" dan "ruang atau akhir string"

127

Bayangkan Anda mencoba untuk mencocokkan pola "stackoverflow".

Anda menginginkan yang berikut:

 this is stackoverflow and it rocks [MATCH]

 stackoverflow is the best [MATCH]

 i love stackoverflow [MATCH]

 typostackoverflow rules [NO MATCH]

 i love stackoverflowtypo [NO MATCH]

Saya tahu cara mengurai stackoverflow jika memiliki spasi di kedua situs menggunakan:

/\s(stackoverflow)\s/

Sama dengan jika pada awal atau akhir suatu string:

/^(stackoverflow)\s/

/\s(stackoverflow)$/

Tetapi bagaimana Anda menentukan "spasi atau akhir string" dan "spasi atau awal string" menggunakan ekspresi reguler?

anonim-satu
sumber

Jawaban:

172

Anda dapat menggunakan salah satu dari yang berikut ini:

\b      #A word break and will work for both spaces and end of lines.
(^|\s)  #the | means or. () is a capturing group. 


/\b(stackoverflow)\b/

Juga, jika Anda tidak ingin memasukkan ruang dalam pertandingan Anda, Anda dapat menggunakan tampilan di belakang / depan.

(?<=\s|^)         #to look behind the match
(stackoverflow)   #the string you want. () optional
(?=\s|$)          #to look ahead.
Jacob Eggers
sumber
8
\badalah pernyataan nol-lebar; tidak pernah mengkonsumsi karakter apa pun. Tidak perlu membungkusnya dengan lookaround.
Alan Moore
2
Perhatikan bahwa di sebagian besar implementasi regexp, \badalah ASCII standar saja , yang mengatakan, tidak ada dukungan unicode. Jika Anda perlu mencocokkan kata-kata unicode, Anda tidak punya pilihan selain menggunakan ini: stackoverflow.com/a/6713327/1329367
Mahn
4
Cara yang lebih mudah untuk mengecualikan pemilihan grup dari pertandingan adalah(?:^|\s)
user2426679
7
untuk python, ganti (?<=\s|^)dengan (?:(?<=\s)|(?<=^)). Jika tidak, Anda mendapatkanerror: look-behind requires fixed-width pattern
user2426679
4
Mereka \bakan mempertimbangkan karakter lain - seperti " ." sebagai pemecah kata, sedangkan penanya secara khusus mengatakan "spasi". solusi @ gordy tampaknya lebih baik.
Mikhail T.
65

(^|\s)akan cocok dengan ruang atau awal string dan ($|\s)untuk ruang atau akhir string. Bersama itu:

(^|\s)stackoverflow($|\s)
bagus
sumber
4
ini satu-satunya yang bekerja untuk saya. terima kasih @gordy
robsonrosa
2
Jika Anda menggunakan pola ini untuk mengganti, ingatlah untuk menjaga spasi di hasil yang diganti dengan mengganti dengan pola $1string$2.
Mahn
Ini adalah satu-satunya yang bekerja untuk saya juga. Batas kata sepertinya tidak pernah melakukan apa yang saya inginkan. Pertama, mereka mencocokkan beberapa karakter selain spasi putih (seperti tanda hubung). Ini menyelesaikannya untuk saya karena saya sudah mencoba untuk memasukkan $dan ^ke dalam kelas karakter, tetapi ini menunjukkan mereka hanya dapat dimasukkan ke dalam kelompok pola biasa.
felwithe
17

Inilah yang akan saya gunakan:

 (?<!\S)stackoverflow(?!\S)

Dengan kata lain, cocokkan "stackoverflow" jika tidak didahului oleh karakter yang bukan spasi dan tidak diikuti oleh karakter yang bukan spasi.

Ini lebih rapi (IMO) daripada pendekatan "ruang-atau-jangkar", dan tidak menganggap string dimulai dan diakhiri dengan karakter kata seperti \bpendekatan yang dilakukan.

Alan Moore
sumber
1
penjelasan yang baik tentang mengapa menggunakan ini. saya akan memilih ini namun string yang diuji SELALU satu baris.
anonim-satu
7

\b cocok dengan batas kata (tanpa benar-benar cocok dengan karakter apa pun), jadi yang berikut harus melakukan apa yang Anda inginkan:

\bstackoverflow\b
Andrew Clark
sumber
Untuk Python akan membantu untuk menentukannya sebagai string mentah , misalnyamystr = r'\bstack overflow\b'
Acumenus