Regex: specificare "spazio o inizio della stringa" e "spazio o fine della stringa"


127

Immagina di provare a abbinare "stackoverflow".

Si desidera quanto segue:

 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]

So come analizzare StackOverflow se ha spazi su entrambi i siti usando:

/\s(stackoverflow)\s/

Lo stesso vale se è all'inizio o alla fine di una stringa:

/^(stackoverflow)\s/

/\s(stackoverflow)$/

Ma come si specifica "spazio o fine della stringa" e "spazio o inizio della stringa" usando un'espressione regolare?

Risposte:


172

Puoi usare uno dei seguenti:

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

Inoltre, se non vuoi includere lo spazio nella tua partita, puoi usare lookbehind / aheads.

(?<=\s|^)         #to look behind the match
(stackoverflow)   #the string you want. () optional
(?=\s|$)          #to look ahead.

8
\bè un'asserzione di larghezza zero; non consuma mai alcun personaggio. Non è necessario avvolgerlo in un lookaround.
Alan Moore,

2
Si noti che nella maggior parte delle implementazioni regexp, \bè solo ASCII standard , vale a dire nessun supporto unicode. Se devi abbinare le parole unicode non hai altra scelta che usarlo invece: stackoverflow.com/a/6713327/1329367
Mahn

4
Il modo più semplice per escludere la selezione del gruppo dalla partita è(?:^|\s)
user2426679,

7
per Python, sostituire (?<=\s|^)con (?:(?<=\s)|(?<=^)). Altrimenti, ottienierror: look-behind requires fixed-width pattern
user2426679

4
Il \bprenderebbe in considerazione altri personaggi - come " ." come parola-breaker, mentre il richiedente ha espressamente detto "spazio". La soluzione di @ gordy sembra migliore.
Mikhail T.

65

(^|\s)corrisponderebbe allo spazio o all'inizio della stringa e ($|\s)allo spazio o alla fine della stringa. Insieme è:

(^|\s)stackoverflow($|\s)

4
questo è l'unico che funziona per me. grazie @gordy
robsonrosa il

2
Se si utilizza questo motivo per sostituirlo, ricordare di mantenere gli spazi nel risultato sostituito sostituendolo con il motivo $1string$2.
Mahn,

Questo è l'unico che funziona anche per me. I confini delle parole non sembrano mai fare quello che voglio. Per uno, abbinano alcuni personaggi oltre agli spazi bianchi (come trattini). Ciò ha risolto per me perché avevo cercato di mettere $e ^in una classe di caratteri, ma questo mostra che può semplicemente essere messo in un gruppo schema regolare.
Felwithe

17

Ecco cosa vorrei usare:

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

In altre parole, abbina "stackoverflow" se non è preceduto da un carattere non bianco e non seguito da un carattere non bianco.

Questo è più ordinato (IMO) dell'approccio "spazio-o-ancora", e non presuppone che la stringa inizi e termini con caratteri di parole come l' \bapproccio.


1
buona spiegazione sul perché utilizzarlo. avrei scelto questo, tuttavia la stringa in fase di test è SEMPRE una riga singola.
anonymous-one

7

\b corrisponde ai confini delle parole (senza corrispondere effettivamente a nessun carattere), quindi quanto segue dovrebbe fare quello che vuoi:

\bstackoverflow\b

Per Python aiuta a indicare una stringa di cruda , per esempiomystr = r'\bstack overflow\b'
Acumenus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.