Wyrażenie regularne: określ „spację lub początek ciągu” i „spację lub koniec ciągu”

127

Wyobraź sobie, że próbujesz dopasować do wzorca „stackoverflow”.

Chcesz, co następuje:

 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]

Wiem, jak przeanalizować przepełnienie stosu, jeśli ma spacje w obu witrynach, używając:

/\s(stackoverflow)\s/

To samo dotyczy sytuacji, gdy znajduje się na początku lub na końcu ciągu:

/^(stackoverflow)\s/

/\s(stackoverflow)$/

Ale jak określić „spację lub koniec ciągu” i „spację lub początek ciągu” za pomocą wyrażenia regularnego?

anonimowy-jeden
źródło

Odpowiedzi:

172

Możesz użyć dowolnego z następujących:

\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/

Ponadto, jeśli nie chcesz uwzględniać spacji w swoim dopasowaniu, możesz użyć lookbehind / aheads.

(?<=\s|^)         #to look behind the match
(stackoverflow)   #the string you want. () optional
(?=\s|$)          #to look ahead.
Jacob Eggers
źródło
8
\bjest asercją o zerowej szerokości; nigdy nie zużywa żadnych znaków. Nie ma potrzeby owijania go wokół.
Alan Moore
2
Zauważ, że w większości implementacji regexp, \bjest to standardowe tylko ASCII , to znaczy brak obsługi Unicode. Jeśli chcesz dopasować słowa Unicode, nie masz innego wyjścia, jak tylko użyć tego zamiast tego: stackoverflow.com/a/6713327/1329367
Mahn,
4
(?:^|\s)
Najłatwiejszym
7
dla Pythona, wymienić (?<=\s|^)z (?:(?<=\s)|(?<=^)). W przeciwnym razie otrzymaszerror: look-behind requires fixed-width pattern
user2426679
4
\bByłoby rozważyć inne postacie - takie jak „ .” jak słowo wyłączników, natomiast Pytający specjalnie powiedział „przestrzeń”. Rozwiązanie @ gordy wydaje się lepsze.
Michaił T.
65

(^|\s)dopasowałoby spację lub początek ciągu i ($|\s)spację lub koniec łańcucha. Razem to:

(^|\s)stackoverflow($|\s)
gordy
źródło
4
to jedyny, który mi pasuje. dziękuję @gordy
robsonrosa
2
Jeśli używasz tego wzorca do zastąpienia, pamiętaj, aby zachować spacje w zastępowanym wyniku, zastępując go wzorem $1string$2.
Mahn
To jedyny, który mi pasuje. Granice słów nigdy nie wydają się robić tego, czego chcę. Po pierwsze, dopasowują niektóre znaki oprócz białych znaków (np. Myślniki). To rozwiązało to dla mnie, ponieważ próbowałem wstawić $i ^do klasy postaci, ale to pokazuje, że można je po prostu umieścić w zwykłej grupie wzorców.
felwithe
17

Oto, czego bym użył:

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

Innymi słowy, dopasuj „stackoverflow”, jeśli nie poprzedza go znak niebędący białą spacją i nie występuje po nim znak niebędący białą spacją.

Jest to ładniejsze (IMO) niż podejście „spacja lub kotwica” i nie zakłada, że ​​łańcuch zaczyna się i kończy znakami słów, tak jak to \brobi podejście.

Alan Moore
źródło
1
dobre wyjaśnienie, dlaczego tego używać. Wybrałbym to, jednak testowany ciąg jest ZAWSZE pojedynczą linią.
anonimowy-jeden
7

\b dopasowuje na granicach słowa (bez faktycznego dopasowywania żadnych znaków), więc poniższe czynności powinny zrobić, co chcesz:

\bstackoverflow\b
Andrew Clark
źródło
W przypadku Pythona pomocne jest określenie surowego ciągu znaków , np.mystr = r'\bstack overflow\b'
Acumenus