¿Cuál es la diferencia entre $ / y $ ¢ en expresiones regulares?


11

Como indica el título, ¿cuál es la diferencia entre $/y ? Parecen tener siempre el mismo valor:

my $text = "Hello world";

$text ~~ /(\w+) { say $/.raku } (\w+)/;
$text ~~ /(\w+) { say $¢.raku } (\w+)/;

Ambos dan como resultado objetos de coincidencia con los mismos valores. ¿Cuál es la lógica en usar uno sobre el otro?

Respuestas:


11

La variable se $/refiere a la coincidencia más reciente, mientras que la variable se refiere a la coincidencia externa más reciente. En la mayoría de las expresiones regulares como la anterior, puede ser una y la misma. Pero como se puede ver en la salida del .rakumétodo, los Matchobjetos pueden contener otros Matchobjetos (eso es lo que obtienes cuando usas $<foo>o $1para las capturas).

Supongamos que tenemos la siguiente expresión regular con una captura cuantificada

/ ab (cd { say $¢.from, " ", $¢.to } ) + /

Y ejecutado, vería el siguiente resultado si coincidiéramos con "abcdcdcd":

0 2
0 4
0 6

Pero si cambiamos de usar a $/, obtenemos un resultado diferente:

2 2
4 4
6 6

(La razón por la que .toparece estar un poco apagado es que, y .pos- no se actualizan hasta el final del bloque de captura).

En otras palabras, será siempre referirse a lo que será el objeto final del partido (es decir, $final = $text ~~ $regex) para que pueda atravesar un complejo en el interior del árbol de captura de la expresión regular exactamente como después haría después de haber terminado el partido completo Así en el ejemplo anterior, sólo podía hacer $¢[0]para referirse al primer partido, $¢[1]el segundo, etc.

Dentro de un bloque de código regex, $/se referirá a la coincidencia más inmediata. En el caso anterior, esa es la coincidencia para dentro ( )y no sabrá sobre las otras coincidencias, ni el inicio original de la coincidencia: solo el inicio del ( )bloque. Así que da una expresión regular más compleja:

/ a $<foo>=(b $<bar>=(c)+ )+ d /

Podemos acceder en cualquier momento usando $ ¢ todos los footokens diciendo $¢<foo>. Podemos acceder a los bartokens de un determinado foomediante $¢<foo>[0]<bar>. Si insertamos un bloque de código dentro de foola captura de 's, podrá acceder a los bartokens usando $<bar>o $/<bar>, pero no podrá acceder a otros foos.


1
Ohhh! Interpreté el documento "La principal diferencia entre $/y es el alcance: este último solo tiene un valor dentro de la expresión regular" en el sentido de que era simplemente un rastro vestigial, tal como Cursores. Cuando leí tu respuesta, pensé que sería la $*TOPque creé en ¿ Una posible mejora? sección de mi respuesta a SO "¿Por qué / cómo se necesita una variable adicional para unir caracteres arbitrarios repetidos con grupos de captura?". Pero mis intentos de reemplazar $*TOPcon fracasaron. ¿Entiendes mi punto en esa respuesta? ¿Puedes hacer que funcione?
raiph

Raiph: Entonces, en las gramáticas, se renueva para cada ficha, por lo que tendrías que decir $*TOP := $¢en la TOPficha pero eso no elimina la necesidad de la $*TOPvar, por supuesto. Estoy de acuerdo en que sería increíble poder referirme a los partidos en un nivel superior. En última instancia, el problema sigue siendo el que identifica: cuando las coincidencias posicionales / hash se publican en el objeto de coincidencia. Cuando se usa , que es por token, los resultados se publicarán por definición tan pronto como { }se encuentre su bloque envolvente .
user0721090601

Lo que es interesante para mí es que en el desarrollo Binex, no he encontrado que sea computacionalmente peor publicar los resultados del partido inmediatamente después de encontrarlos. Al final del día, está presionando / haciendo estallar, ya sea a una lista / hash en caché, o está presionando / haciendo estallar a la lista / hash del Partido. Sin embargo, puede haber algún tipo de aceleración interna que no conozco utilizada para LTM, que probablemente sea el núcleo de la misma ( { }termina un token a los efectos de LTM, por lo que es más probable que se ejecute / pruebe que el resto del token en una |agrupación)
user0721090601

Ahhh Había llegado a la conclusión de que era dinámico, y me sorprendió cuando no funcionó. Pero ahora se ha caído el centavo de que es léxico, como podría haber adivinado dado su uso de la palabra "más externo", y se explica, como usted explica, al comienzo de cada regla.
raiph

Por lo tanto, al comienzo de una regla, se crea un nuevo objeto de coincidencia que registra la posición del cursor del motor de coincidencia dentro de la cadena de entrada original, pero por lo demás está vacía. (¿Correcto?) Entonces, y $/están vinculados al mismo objeto, a saber, este nuevo objeto de coincidencia, que registrará lo que esta regla coincide y captura a medida que avanza. Luego, a medida que avanza la coincidencia, permanece vinculado a este objeto de coincidencia general, mientras que $/se recupera cada vez que se crea un nuevo objeto de coincidencia, por lo que siempre corresponde, como usted dice, al último objeto de coincidencia. ¿Derecha?
raiph
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.