AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / coding / Perguntas / 79182638
Accepted
Hovercouch
Hovercouch
Asked: 2024-11-13 04:32:09 +0800 CST2024-11-13 04:32:09 +0800 CST 2024-11-13 04:32:09 +0800 CST

"O melhor truque de Regex" em Raku

  • 772

O Melhor Truque de Regex é sobre escrever regexes que correspondem, r1mas não r2. O exemplo que eles dão é um regex que corresponde a Tarzan(e "Tarzan and Jane"), mas não "Tarzan". Depois de passar por algumas coisas que não funcionam, eles dão o "melhor truque de regex de todos os tempos":

"Tarzan"|(Tarzan)

Isso supostamente corresponde à "string ruim" primeiro, pulando a string boa, mas não incluindo a string ruim em um grupo de captura. Se apenas a string boa aparecer, nós correspondemos nela por último e a incluímos no grupo de captura.

Uma desvantagem do "melhor truque de regex" é que isso ainda corresponde a "Tarzan" , mesmo que não o capture . Você não pode, por exemplo, usá-lo em um condicional sem algum boilerplate extra?

Isto é baseado em regexes estilo PCRE. O Raku usa uma notação regex completamente diferente. É possível fazer o truque de forma mais simples? Idealmente, isto deveria ser possível:

> ('"Tarzan"', 'Tarzan', '"Tarzan and Jane"') <<~~>> /some-regex/
(Nil 「Tarzan」 「Tarzan」)
regex
  • 4 4 respostas
  • 125 Views

4 respostas

  • Voted
  1. Best Answer
    raiph
    2024-11-13T13:35:22+08:002024-11-13T13:35:22+08:00

    Primeiro, um equivalente direto, mas idiomático, de "O Melhor Truque de Regex" no Raku:

    say ( .[0] for ( « '"Tarzan"' Tarzan '"Tarzan and Jane"' » «~~» / '"Tarzan"' | (Tarzan) / ) )
    
    # (Nil 「Tarzan」 「Tarzan」)
    

    Notas:

    • Vi que você estava familiarizado com a construção «op» do operador meta do Raku para mapear sucintamente a correspondência em várias entradas. Usei isso mais a construção « ... » de citação de termos do Raku para especificar sucintamente a entrada de correspondência.
    • Eu escrevi '"Tarzan"'em vez de "Tarzan"no padrão regex. Ao contrário dos dialetos regex mais antigos, o Raku trata o código da forma "foo"em um regex como representando a string de três caracteres foo. Uma maneira de representar a string de cinco"foo" caracteres é escrever '"foo"'.
    • Capturas de grupo no Raku são numeradas de zero, não de um, então a (Tarzan)captura de grupo é captura zero . Portanto, o código says .[0]not .[1].

    é possível fazer o truque de forma mais simples?

    Um passo que pode ser considerado na direção certa é:

    say ( $_ for ( « '"Tarzan"' Tarzan '"Tarzan and Jane"' » «~~» / '"Tarzan"' <()> | <(Tarzan)> / ) )
    
    # (「」 「Tarzan」 「Tarzan」)
    

    Notas:

    • <(...)>delimita explicitamente a captura de nível superior, estreitando-a em relação à captura de nível superior padrão (que captura tudo o que corresponde).
    • <()>significa que a captura de nível superior está vazia . Não é Nil, mas pode ser suficiente dependendo das suas necessidades.
    • <(Tarzan)>especifica a captura de nível superior (em contraste com (Tarzan)o que especifica a primeira subcaptura ).

    A especificação original para regexes Raku incluía alguns recursos relevantes que ainda não foram implementados. É possível que eles sejam implementados um dia e forneçam uma solução mais simples.


    Veja também a resposta de @tshiono.


    Veja também a excelente resposta de @alatennaub no reddit .

    • 8
  2. tshiono
    2024-11-13T11:25:29+08:002024-11-13T11:25:29+08:00

    Como você mencionou, o Raku usa uma notação regex completamente diferente. Você poderia tentar:

    > ('"Tarzan"', 'Tarzan', '"Tarzan and Jane"') <<~~>> / <!after \">Tarzan | Tarzan<!before \"> /
    

    Resultado:

    (Nil 「Tarzan」 「Tarzan」)
    
    • <!after \">denota a afirmação negativa de olhar para trás.
    • <!before \">denota a afirmação de previsão negativa.
    • O caractere de aspas duplas deve ser escapado.
    • A alternância |pode ser cercada por espaços em branco.
    • 6
  3. codesections
    2024-11-13T22:35:19+08:002024-11-13T22:35:19+08:00

    Idealmente isso deveria ser possível:

    > ('"Tarzan"', 'Tarzan', '"Tarzan and Jane"') <<~~>> /some-regex/ 
    (Nil 「Tarzan」 「Tarzan」) 
    

    Isso é perto o suficiente?

    > (('"Tarzan"', 'Tarzan', '"Tarzan and Jane"') <<~~>> / '"Tarzan"' || ('Tarzan') /)»[0] 
    (Nil 「Tarzan」 「Tarzan」) 
    

    Ou, um pouco mais claro na minha opinião:

    > (['"Tarzan"', 'Tarzan', '"Tarzan and Jane"'] «~~» / '"Tarzan"' || ('Tarzan') /)»[0] 
    (Nil 「Tarzan」 「Tarzan」) 
    

    Ou se você for usar o idioma "extrair a primeira captura de uma correspondência" o tempo todo, você pode até mesmo definir a composição de ~~e [0]como um novo operador (aqui,~~[0]

    my &infix:<~~[0]> = *[0] ∘ &[~~]; 
    ('"Tarzan"', 'Tarzan', '"Tarzan and Jane"') «~~[0]» / '"Tarzan"' || ('Tarzan') /;
    # Returns (Nil 「Tarzan」 「Tarzan」) 
    

    Mas isso provavelmente é um exagero! (E também tem que estar em uma linha no REPL devido a um bug).

    (Tudo isso se baseia na excelente resposta do reddit de @alatennaub que @raiph já mencionou. Confira essa resposta para ver maneiras de evitar a correspondência com `"Tarzan"', o que evita a necessidade de selecionar a primeira captura)

    • 5
  4. librasteve
    2024-11-13T18:01:39+08:002024-11-13T18:01:39+08:00

    Como sempre, aprendi muito com @raiph e esta resposta é um pequeno refinamento da dele, espero que com um pouco mais de espaço:

    my @tests = [ '"Tarzan"', 'Tarzan', '"Tarzan and Jane"' ];
    
    my regex reg { 
        '"' ~ '"' 'Tarzan'              # non-capturing when double quoted
        |                               # otherwise
        ('Tarzan')                      # capture with ()  
    } 
     
    say .<reg>[0] for ( @tests «~~» /<reg>/ );
    

    Notas:

    1. pessoalmente fiquei um pouco confuso com o « ... »termo citação
    2. parece mais limpo definir o @testse regexseparadamente
    3. Gosto do espaço para respirar e dos comentários abundantes de @alatennaub
    4. Eu uso o ~til para equilibrar a correspondência de ambos"
    • 2

relate perguntas

  • Regex: Corresponde até "," mas não se "," estiver entre colchetes

  • encontre o número enésimo da string e divida o ['8','th'] assim usando dart

  • Faça uma nova linha após 3 caracteres após regex

  • Antevisão positiva no regex do Google Sheets

  • Como usar a renomeação do Perl no terminal do macOS para substituir nomes de arquivos aleatórios por string e índice personalizados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Vue 3: Erro na criação "Identificador esperado, mas encontrado 'import'" [duplicado]

    • 1 respostas
  • Marko Smith

    Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle?

    • 1 respostas
  • Marko Smith

    Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores?

    • 1 respostas
  • Marko Smith

    Como faço para corrigir um erro MODULE_NOT_FOUND para um módulo que não importei manualmente?

    • 6 respostas
  • Marko Smith

    `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso?

    • 3 respostas
  • Marko Smith

    Quando devo usar um std::inplace_vector em vez de um std::vector?

    • 3 respostas
  • Marko Smith

    Um programa vazio que não faz nada em C++ precisa de um heap de 204 KB, mas não em C

    • 1 respostas
  • Marko Smith

    PowerBI atualmente quebrado com BigQuery: problema de driver Simba com atualização do Windows

    • 2 respostas
  • Marko Smith

    AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos

    • 1 respostas
  • Marko Smith

    Estou tentando fazer o jogo pacman usando apenas o módulo Turtle Random e Math

    • 1 respostas
  • Martin Hope
    Aleksandr Dubinsky Por que a correspondência de padrões com o switch no InetAddress falha com 'não cobre todos os valores de entrada possíveis'? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge Por que esse código Java simples e pequeno roda 30x mais rápido em todas as JVMs Graal, mas não em nenhuma JVM Oracle? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini Qual é o propósito de `enum class` com um tipo subjacente especificado, mas sem enumeradores? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(expression, lvalue) = rvalue` é uma atribuição válida em C ou C++? Por que alguns compiladores aceitam/rejeitam isso? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer Quando devo usar um std::inplace_vector em vez de um std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller O ponto e vírgula agora é opcional em condicionais bash com [[ .. ]] na versão 5.2? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench Por que um traço duplo (--) faz com que esta cláusula MariaDB seja avaliada como verdadeira? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng Por que `dict(id=1, **{'id': 2})` às vezes gera `KeyError: 'id'` em vez de um TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob: MobileAds.initialize() - "java.lang.Integer não pode ser convertido em java.lang.String" para alguns dispositivos 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB Por que o GCC gera código que executa condicionalmente uma implementação SIMD? 2024-02-17 06:17:14 +0800 CST

Hot tag

python javascript c++ c# java typescript sql reactjs html

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve