Regex: especifique "espacio o inicio de cadena" y "espacio o final de cadena"

127

Imagine que está tratando de hacer coincidir el patrón "stackoverflow".

Quieres lo siguiente:

 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]

Sé cómo analizar stackoverflow si tiene espacios en ambos sitios usando:

/\s(stackoverflow)\s/

Lo mismo con si está al principio o al final de una cadena:

/^(stackoverflow)\s/

/\s(stackoverflow)$/

Pero, ¿cómo se especifica "espacio o final de cadena" y "espacio o inicio de cadena" utilizando una expresión regular?

anónimo uno
fuente

Respuestas:

172

Puede usar cualquiera de los siguientes:

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

Además, si no quieres incluir el espacio en tu partida, puedes usar lookbehind / aheads.

(?<=\s|^)         #to look behind the match
(stackoverflow)   #the string you want. () optional
(?=\s|$)          #to look ahead.
Jacob Eggers
fuente
8
\bes una afirmación de ancho cero; nunca consume ningún personaje. No hay necesidad de envolverlo en una búsqueda.
Alan Moore
2
Tenga en cuenta que en la mayoría de las implementaciones regexp, solo \bes ASCII estándar , es decir, no es compatible con Unicode. Si necesita unir palabras Unicode, no tiene más remedio que usar esto en su lugar: stackoverflow.com/a/6713327/1329367
Mahn
44
La forma más fácil de excluir la selección de grupo del partido es(?:^|\s)
user2426679
77
para python, reemplace (?<=\s|^)con (?:(?<=\s)|(?<=^)). De lo contrario, obtendráerror: look-behind requires fixed-width pattern
user2426679
44
El \bconsideraría otros caracteres, como " ." como separadores de palabras, mientras que el autor de la pregunta dijo específicamente "espacio". La solución de @ gordy parece mejor.
Mikhail T.
65

(^|\s)coincidiría con el espacio o el inicio de la cadena y ($|\s)para el espacio o el final de la cadena. Juntos es:

(^|\s)stackoverflow($|\s)
gordy
fuente
44
Este es el único que funciona para mí. gracias @gordy
robsonrosa
2
Si usa este patrón para reemplazar, recuerde mantener los espacios en el resultado reemplazado reemplazando con el patrón $1string$2.
Mahn
Este es el único que también funciona para mí. Los límites de las palabras nunca parecen hacer lo que quiero. Por un lado, coinciden con algunos caracteres además del espacio en blanco (como guiones). Esto lo resolvió para mí porque había estado tratando de poner $y ^en una clase de caracteres, pero esto muestra que sólo se puede poner en un grupo patrón regular.
Felwithe
17

Esto es lo que usaría:

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

En otras palabras, haga coincidir "stackoverflow" si no está precedido por un carácter que no sea un espacio en blanco y no esté seguido por un carácter que no sea un espacio en blanco.

Esto es más ordenado (IMO) que el enfoque de "espacio o ancla", y no asume que la cadena comienza y termina con caracteres de palabras como lo hace el \benfoque.

Alan Moore
fuente
1
buena explicación de por qué usar esto. Hubiera elegido esto, sin embargo, la cadena que se prueba es SIEMPRE una sola línea.
anónimo-uno
7

\b coincide en los límites de las palabras (sin coincidir con ningún carácter), por lo que lo siguiente debe hacer lo que desee:

\bstackoverflow\b
Andrew Clark
fuente
Para Python, ayuda a especificar una cadena sin procesar , por ejemplomystr = r'\bstack overflow\b'
Acumenus