span compile python regex string substring

compile - re python doc



¿Por qué la búsqueda de expresiones regulares en la subcadena "no es completamente equivalente a cortar la cadena" en Python? (2)

Como se indica en la documentation , el uso de regex.search(string, pos, endpos) no es completamente equivalente a cortar la cadena, es decir, regex.search(string[pos:endpos]) . No hará una coincidencia de expresiones regulares como si la cadena comenzara desde pos , por lo que ^ no coincide con el principio de la subcadena , sino que solo coincide con el principio real de toda la cadena. Sin embargo, $ coincide con el final de la subcadena o con toda la cadena.

>>> re.compile(''^am'').findall(''I am falling in code'', 2, 12) [] # am is not at the beginning >>> re.compile(''^am'').findall(''I am falling in code''[2:12]) [''am''] # am is the beginning >>> re.compile(''ing$'').findall(''I am falling in code'', 2, 12) [''ing''] # ing is the ending >>> re.compile(''ing$'').findall(''I am falling in code''[2:12]) [''ing''] # ing is the ending >>> re.compile(''(?<= )am'').findall(''I am falling in code'', 2, 12) [''am''] # before am there is a space >>> re.compile(''(?<= )am'').findall(''I am falling in code''[2:12]) [] # before am there is no space >>> re.compile(''ing(?= )'').findall(''I am falling in code'', 2, 12) [] # after ing there is no space >>> re.compile(''ing(?= )'').findall(''I am falling in code''[2:12]) [] # after ing there is no space >>> re.compile(r''/bm.....'').findall(''I am falling in code'', 3, 11) [] >>> re.compile(r''/bm.....'').findall(''I am falling in code''[3:11]) [''m fall''] >>> re.compile(r''.....n/b'').findall(''I am falling in code'', 3, 11) [''fallin''] >>> re.compile(r''.....n/b'').findall(''I am falling in code''[3:11]) [''fallin'']

Mis preguntas son ... ¿Por qué no es coherente entre el inicio y el final ? ¿Por qué usar pos y endpos trata el final como el final real, pero el inicio / comienzo no se trata como el comienzo / comienzo real?

¿Hay algún enfoque para hacer que el uso de pos y endpos imiten el corte? Como Python copia la cadena al cortar en lugar de solo hacer referencia a la antigua, sería más eficiente usar pos y endpos lugar de cortar cuando se trabaja con la cadena grande varias veces.


El argumento pos posición inicial es especialmente útil para hacer analizadores léxicos, por ejemplo. La diferencia de rendimiento entre cortar una cadena con [pos:] y usar el parámetro pos puede parecer insignificante, pero ciertamente no lo es; Ver por ejemplo este informe de error en el lexer JsLex .

De hecho, el ^ coincide con el comienzo real de la cadena; o, si se especifica MULTILINE , también al principio de la línea; esto también es así por diseño, de modo que un escáner basado en expresiones regulares pueda distinguir fácilmente entre el comienzo real de la línea / comienzo de la entrada y solo algún otro punto en una línea / dentro de la entrada.

Tenga en cuenta que también puede usar la función regex.match(string[, pos[, endpos]]) para anclar la coincidencia a la cadena de inicio o en la posición especificada por pos ; asi en lugar de hacer

>>> re.compile(''^am'').findall(''I am falling in code'', 2, 12) []

En general, se implementaría un escáner como

>>> match = re.compile(''am'').match(''I am falling in code'', 2, 12) >>> match <_sre.SRE_Match object; span=(2, 4), match=''am''>

y luego establezca la pos en match.end() (que en este caso devuelve 4) para las sucesivas operaciones de coincidencia.

El partido debe encontrarse exactamente en la pos :

>>> re.compile(''am'').match(''I am falling in code'', 1, 12) >>>

(Observe cómo el .match está anclado al comienzo de la entrada como si fuera implícito ^ pero no al final de la entrada; de hecho, esto es a menudo una fuente de errores, ya que las personas creen que la coincidencia tiene ambos, implícito ^ y $ - Python 3.4 Agregado el regex.fullmatch que hace esto)

En cuanto a por qué el parámetro endpos no es coherente con la pos , eso no lo sé exactamente, pero también tiene sentido para mí, ya que en Python 2 no hay una fullmatch y el anclaje con $ es la única manera de garantizar que todo el lapso debe coincidir.


Esto suena como un error en Python, pero si desea hacer un corte por referencia en lugar de copiar las cadenas, puede usar el buffer incorporado de Python.

Por ejemplo:

s = "long string" * 100 buf = buffer(s) substr = buf([5:15])

Esto crea una subcadena sin copiar los datos, por lo que debería permitir una división eficiente de cadenas grandes.