La expresión regular de Python no coincide en el límite de la palabra como se requiere

Quiero hacer coincidir un conjunto de patrones en el “límite de palabra”, pero los patrones pueden tener un prefijo [# @] que debería coincidir si está presente.

Estoy usando el siguiente patrón regex en python.

  r "\ b [@ #]? (abc | ef | ghij) \ b" 

El texto de muestra es: #abc is a pattern which should match. also abc should match. And finally @ef #abc is a pattern which should match. also abc should match. And finally @ef

En este texto solo se comparan abc, abc y ef, y no #abc y @ef como quiero.

Debe colocar el límite de la palabra junto a [@#] que creó como opcional. Debido a que en esta parte #abc hay un límite sin palabra \B existe antes de # ( no es un carácter de palabra ) y después del inicio de la línea ( no es un carácter de palabra ) no hay un límite de palabra \b . Tenga en cuenta que \b coincide entre un carácter de palabra y un carácter que no es de palabra, y viceversa. \B coincide entre dos caracteres de palabras o dos caracteres que no son palabras.

 r"[@#]?\b(abc|ef|ghij)\b" 

Si colocas \b antes de [@#] , coincidiría con cadenas como foo@abc o bar#abc porque aquí hay un límite de palabra antes de @ y # .

MANIFESTACIÓN

Ejemplo:

 >>> s = "#abc is a pattern which should match. also abc should match. And finally @ef" >>> re.findall(r'[@#]?\b(?:abc|ef|ghij)\b', s) ['#abc', 'abc', '@ef'] #abc ^ ^ \B \b 

El grupo (@#)? está diciendo que la palabra puede comenzar con “@ #”. ¿Qué estás buscando es [@#]? que dice que el primer carácter es @ o #, pero no es obligatorio. Si necesita que la coincidencia sea parte de un grupo que podría usar (@|#)? .

También agregaré mi versión de la expresión regular fija sin capturar el grupo (ya que parece que no los estás usando):

 r'[@#]?\b(?:abc|ef|ghij)\b' 

Mira mi demo .

EXPLICACIÓN : [@#] son caracteres sin palabra y son opcionales debido a ? . \b no es opcional, y el motor de expresiones regulares lo consume primero, es decir, consume la derecha @ o # , pero no son parte de la coincidencia, ya que \b es siempre de ancho cero .

Aquí hay más detalles sobre \b de Regular-Expressions.info :

El metacarácter \ b es un ancla como el cursor y el signo del dólar. Coincide en una posición que se llama “límite de palabra”. Este partido es de longitud cero .

Hay tres posiciones diferentes que califican como límites de palabras:

  • Antes del primer carácter de la cadena, si el primer carácter es un carácter de palabra.
  • Después del último carácter de la cadena, si el último carácter es un carácter de palabra.
  • Entre dos caracteres en la cadena, donde uno es un carácter de palabra y el otro no es un carácter de palabra.