2009-02-08 9 views
34

¿Puede una expresión regular hacer coincidir los espacios en blanco o el comienzo de una cadena?Expresión regular: partida de inicio o espacio en blanco

Estoy tratando de reemplazar moneda con la abreviatura GBP con un símbolo £. Podría igualar cualquier cosa que empiece en GBP, pero me gustaría ser un poco más conservador y buscar ciertos delimitadores a su alrededor.

>>> import re 
>>> text = u'GBP 5 Off when you spend GBP75.00' 

>>> re.sub(ur'GBP([\W\d])', ur'£\g<1>', text) # matches GBP with any prefix 
u'\xa3 5 Off when you spend \xa375.00' 

>>> re.sub(ur'^GBP([\W\d])', ur'£\g<1>', text) # matches at start only 
u'\xa3 5 Off when you spend GBP75.00' 

>>> re.sub(ur'(\W)GBP([\W\d])', ur'\g<1>£\g<2>', text) # matches whitespace prefix only 
u'GBP 5 Off when you spend \xa375.00' 

¿Puedo hacer los dos últimos ejemplos al mismo tiempo?

+0

¿Qué idioma es este? ¿Es Perl? –

+0

Python. –

+0

Sí Python, pero el concepto es el mismo independientemente. – Mat

Respuesta

38

Use o "|" operador:

>>> re.sub(r'(^|\W)GBP([\W\d])', u'\g<1>£\g<2>', text) 
u'\xa3 5 Off when you spend \xa375.00' 
+1

Excelente. Supuse que se lo obligaron a estar al principio de la cadena. Cambio menor necesario para mantener el espaciado: re.sub (u '(^ | \ W) GBP ([\ W \ d])', u '\ g <1> £ \ g <2>', texto). Aceptado por ser la solución más intuitiva para mi problema inmediato. – Mat

+0

@Mat: Gracias, he actualizado mi respuesta como se sugiere. –

24

\b es límite de palabra, que puede ser un espacio en blanco, el comienzo de una línea o un símbolo no alfanumérico (\bGBP\b).

+1

Cool. Aprendí dos cosas de tu respuesta.1. Nunca antes había usado límites de palabras en expresiones regulares. 2. Las cosas (particularmente \ b) no funcionan bien si accidentalmente usa los prefijos u '' en lugar de r '' en las expresiones regulares de Python. – Mat

+0

@Mat: Por supuesto, podría usar su "myregex" – nosklo

+0

Cool. Eso tiene sentido ahora que lo mencionas. – Mat

1

Sí, ¿por qué no?

re.sub(u'^\W*GBP... 

coincide con el inicio de la cadena, 0 o más espacios en blanco, a continuación, GBP ...

edición: Oh, creo que usted quiere alternancia, utilice el |:

re.sub(u'(^|\W)GBP... 
0

Siempre puede recortar el espacio en blanco inicial y final del token antes de buscar si no se trata de una situación de coincidencia/agrupamiento que requiera la línea completa.

6

Esto reemplaza GBP si está precedida por el inicio de una cadena o una word boundary (que el inicio de una cadena ya lo es), y después de GBP llega un valor numérico o un límite de palabra:

re.sub(u'\bGBP(?=\b|\d)', u'£', text) 

Este elimina la necesidad de una referencia innecesaria utilizando un lookahead. ¿Incluido lo suficiente?

+0

"\ d +": el signo más no es necesario – tzot

+0

Tiene razón, de hecho la mayoría de los motores de expresiones regulares no permiten la repetición y solo algunos a través de repeticiones fijas {MIN, MAX} dentro de las alternativas que hacen que \ d + sea inválido. Era consciente, pero lo extrañé por completo, así que gracias he editado en consecuencia :) –

+0

@Martijn, que solo se aplica a lookBEHINDs; lookAHEADs no tienen tal limitación (al menos, no en ningún sabor con el que esté familiarizado). –

2

Creo que estás buscando '(^|\W)GBP([\W\d])'

0

Funciona en Perl:

$text = 'GBP 5 off when you spend GBP75'; 
$text =~ s/(\W|^)GBP([\W\d])/$1\$$2/g; 
printf "$text\n"; 

la salida es:

$ 5 off when you spend $75 

Tenga en cuenta que estipulé que la coincidencia debería ser global, para obtener todas las instancias.

Cuestiones relacionadas