Qual é a diferença entre $ / e $ ¢ no regex?


11

Como o título indica, qual é a diferença entre $/e ? Eles parecem sempre ter o mesmo valor:

my $text = "Hello world";

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

Ambos resultam em objetos de correspondência com os mesmos valores. Qual é a lógica em usar um sobre o outro?

Respostas:


11

A variável $/refere-se à correspondência mais recente, enquanto a variável refere-se à correspondência mais externa mais recente. Nas regexes mais básicas, como a acima, isso pode ser o mesmo. Mas, como pode ser visto na saída do .rakumétodo, os Matchobjetos podem conter outros Matchobjetos (é o que você obtém quando usa $<foo>ou $1para capturas).

Suponhamos que tivéssemos a seguinte expressão regular com uma captura quantificada

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

E executou, veria a seguinte saída se comparássemos com "abcdcdcd":

0 2
0 4
0 6

Mas se mudarmos de usar para $/, obteremos um resultado diferente:

2 2
4 4
6 6

(O motivo pelo qual .toparece um pouco errado é que ele .pos- e - não é atualizado até o final do bloco de captura).

Em outras palavras, irá sempre se referir ao que será seu objeto partida final (ou seja, $final = $text ~~ $regex) para que você possa percorrer um complexo dentro árvore captura do regex exatamente como seria depois de ter terminado o jogo completo Assim, no exemplo acima, você poderia apenas faça $¢[0]para se referir à primeira partida, $¢[1]à segunda, etc.

Dentro de um bloco de código regex, $/fará referência à correspondência mais imediata. No caso acima, essa é a partida para dentro da ( )e não saberá sobre as outras partidas, nem o início original da partida: apenas o começo do ( )bloco. Portanto, dê uma regex mais complexa:

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

Podemos acessar a qualquer momento usando $ ¢ todos os footokens dizendo $¢<foo>. Podemos acessar os bartokens de um dado foousando $¢<foo>[0]<bar>. Se inserirmos um bloco de código dentro da foocaptura, ele poderá acessar os bartokens usando $<bar>ou $/<bar>, mas não poderá acessar outros foo.


11
Ohhh! Interpretei o documento "A principal diferença entre $/e é o escopo: o último só tem um valor dentro do regex" para significar que era apenas um vestígio vestigial, exatamente como Cursoré. Quando li sua resposta, pensei que seria o que $*TOPeu criei na possível melhoria? seção da minha resposta para a SO "Por que / como é necessária uma variável adicional para combinar caracteres arbitrários repetidos com grupos de captura?". Mas minhas tentativas de substituir $*TOPpor falharam. Você entende meu ponto nessa resposta? Você pode fazer isso funcionar?
raiph 27/04

Raiph: Então, nas gramáticas, é renovado para cada token, então você teria que dizer $*TOP := $¢no TOPtoken, mas isso não elimina a necessidade do $*TOPvar, é claro. Eu concordo que seria incrível poder se referir às partidas em um nível superior. O problema, finalmente, ainda é o que você identifica: quando a posição / hash corresponde à postagem no objeto de correspondência. Ao usar - que é por token - os resultados serão por definição publicados assim que o { }bloco anexo for encontrado.
user0721090601 27/04

O que é interessante para mim é que, no desenvolvimento Binex, não achei pior computacionalmente postar resultados de correspondências imediatamente após encontrá-los. No final do dia, você está pressionando / aparecendo em uma lista / hash em cache ou pressionando / aparecendo na lista / hash da Correspondência. No entanto, pode haver algum tipo de velocidade interna que eu não conheço usada para o LTM, o que provavelmente está no centro dele (ele { }encerra um token para os fins do LTM e, portanto, é mais provável que seja executado / testado do que o restante do token em um |agrupamento)
user0721090601

Ahhh. Eu pulei para a conclusão de que era dinâmico e fiquei surpreso quando não funcionou. Mas o centavo caiu agora que é lexical, como eu poderia ter adivinhado, devido ao uso da palavra "mais externo", e é, como você explica, estabelecido no início de cada regra.
raiph 27/04

Portanto, iiuc, no início de uma regra, é criado um novo objeto de correspondência que registra a posição do cursor do mecanismo correspondente dentro da cadeia de entrada original, mas está vazio. (Certo?) Então, e $/são vinculados ao mesmo objeto, a saber, esse novo objeto de correspondência, que registrará o que essa regra corresponde e captura à medida que avança. Então, à medida que a correspondência progride, permanece vinculada a esse objeto de correspondência geral, enquanto $/é recuperada toda vez que um novo objeto de correspondência é criado, portanto, sempre corresponde, como você diz, ao objeto de correspondência mais recente. Direita?
raiph 27/04
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.