2010-11-29 11 views
5

Tengo aquí un código heredado mal comentado que hace uso de boost::regex::perl. Me estaba preguntando sobre una construcción en particular antes, pero como el código funcionaba (más o menos), me resistía a tocarlo.boost :: regex - bb?

Ahora tengo tocarlo, por razones técnicas (más precisamente, las versiones actuales de Boost ya no acepta la construcción), así que tengo que averiguar lo que hace - o más bien, era previsto que hacer.

La parte pertinente de la expresión regular:

(?<!(\bb\s|\bb|^[a-z]\s|^[a-z])) 

La pieza que me da dolores de cabeza es \bb. Sé de \b, pero no pude encontrar la mención de \bb, y buscar un literal 'b' no tendría sentido aquí. ¿Es \bb alguna característica especial no documentada, o debo considerar esto como un error tipográfico?

+2

Podría no simplemente probar si '\ bb' partidos "b" (y no "a") para comprobar si en realidad hace algo más que el límite de palabras, seguido de "b"? – Jens

+0

Bueno, el problema -como ocurre con todos los códigos sin comentario- es que lo que * sí * no se correlaciona realmente con lo que * pretendía * hacer. Tendría que probarlo en comparación con la versión actual (1.34.1) y actual de Boost, y * todavía * tendría que adivinar la intención del autor ... – DevSolar

+0

Lea la fuente, Lucas (de impulso :: regex :: perl eso es ... buena suerte :) –

Respuesta

3

(\bb\s|\bb|^[a-z]\s|^[a-z]) coincide con una b si no está precedido por otro carácter de palabra, o cualquier letra minúscula si es al principio de la cadena. En cualquier caso, la letra puede ir seguida de un carácter de espacio en blanco. (Podría coincidir con letras mayúsculas también si se establece el modo de mayúsculas y minúsculas, y el ^ también podría coincidir con el comienzo de una línea si se establece modo multilínea.)

Pero dentro de una búsqueda hacia atrás, que no debería tener incluso compilado. En algunos sabores, un lookbehind puede contener múltiples alternativas con diferentes longitudes fijas, pero la alternancia tiene que estar en el nivel superior en el lookbehind. Es decir, (?<=abc|xy|12345) funcionará, pero (?<=(abc|xy|12345)) no lo hará.Así que su expresión regular no funcionaría incluso en esos sabores, pero los documentos de Boost solo dicen que la expresión lookbehind debe ser de longitud fija.

Si realmente necesita para dar cuenta de las cuatro posibilidades que emparejados por expresiones regulares, que sugieren dividir la búsqueda hacia atrás en dos:

(?<!\bb|^[a-z])(?<!(?:\bb|^[a-z])\s) 
+0

+1 para señalar que "la alternancia tiene que estar en el nivel superior en el aspecto detrás". – DevSolar

4

Como Boost parece ser un motor de expresiones regulares para C++, y uno de los modos de compatibilidad es la compatibilidad Perl - si que es una expresión "compatible con Perl", que el segundo 'b' puede ser solamente un literal.

Es una expresión válida, más o menos un caso especial para palabras que comienzan con 'b'.

Parece ser el factor decisivo que se trata de una biblioteca de C++, y que es para dar entornos que no son perl, expresiones regulares perl-compatibles. Por lo tanto, mi pensamiento original de que perl podría interpretar la expresión (por ejemplo, con overload::constant) no es válido. Sin embargo, todavía vale la pena mencionarlo solo para fines de aclaración, independientemente de cuán desaconsejable sería modificar una expresión que significa "palabra que comienza con 'b'".

La única salvedad de que la idea es que quizá Boost supera a Perl en él es propias expresiones y alguien estaría utilizando el motor Boost en un entorno Perl, todas las apuestas están apagadas en cuanto a si que podría tener ha sido significado como una expresión especial. ¡Esto es solo una puñalada, dada una gramática donde '!!!' significaba algo especial al comienzo de las palabras, se puede superponer sobre el significado establecido como esto (no recomendado!)

s/\\bb\b/(?:!!!(\\p{Alpha})|\\bb)/ 

Esto sería algo tonto como para hacerlo, pero como se trata de código que parece ser aptos para el tarea, hay miles de formas de fallar en una tarea.