Interpolando uma Cadeia de Caracteres em uma Regex


160

Preciso substituir o valor de uma string na minha expressão regular em Ruby. Existe uma maneira fácil de fazer isso? Por exemplo:

foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 
if goo =~ /value of foo here dynamically/
  puts "success!"
end

Você está tentando ver se foo é uma substring de goo? Não acho claro o que você está perguntando.
Neall 29/09/08

Se sim, goo.include? (Foo) é suficiente!
Glenn McDonald

1
Não, eu não estava tentando ver se foo é uma substring de goo; Eu também precisava fazer algumas capturas, portanto, incluir não funcionou.
Chris Bunch

Respostas:



125

Note que o Regexp.quoteem resposta de Jon L. é importante!

if goo =~ /#{Regexp.quote(foo)}/

Se você acabou de fazer a versão "óbvia":

if goo =~ /#{foo}/

os períodos no texto da correspondência serão tratados como curingas de expressão regular e "0.0.0.0"corresponderão "0a0b0c0".

Observe também que, se você realmente deseja apenas verificar uma correspondência de substring, pode simplesmente fazer

if goo.include?(foo)

que não requer uma citação adicional ou se preocupa com caracteres especiais.


3
Observe que o inverso (sem usar .quote()) também pode ser útil se você estiver procurando construir uma regex usando uma string.
Jesse

"se você realmente quer apenas verificar se há uma correspondência de substring, pode simplesmente if goo.include?(foo)" => True quando estiver interessado em verificar a existência. Se você estiver interessado em substituir e já usar o String.gsub, o Regexp.quote pode ser sua única opção.
Isaac Betesh

Só para acrescentar sobre a Jesse no caso não é óbvio, isso significa apenas passando a cadeia de caracteres que você não precisa escaparam ao Regexp.newou Regexp.compile.
dylankb

Obrigado pela explicação útil de por que podemos usar o Regexp.quote #
Wylliam Judd 22/10/1918

7

Provavelmente Regexp.escape(foo)seria um ponto de partida, mas há uma boa razão para você não usar a interpolação de expressão mais convencional "my stuff #{mysubstitutionvariable}":?

Além disso, você pode apenas usar !goo.match(foo).nil?com uma string literal.




3

Aqui está uma outra resposta limitada, mas útil:

Eu descobri que posso inserir facilmente em uma regex sem usar Regexp.quote ou Regexp.escape se eu apenas use aspas simples na minha string de entrada: (uma correspondência de endereço IP)

IP_REGEX = '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'

my_str = "192.0.89.234 blahblah text 1.2, 1.4" # get the first ssh key 
# replace the ip, for demonstration
my_str.gsub!(/#{IP_REGEX}/,"192.0.2.0") 
puts my_str # "192.0.2.0 blahblah text 1.2, 1.4"

aspas simples interpretam apenas \\ e \ '.

http://en.wikibooks.org/wiki/Ruby_Programming/Strings#Single_quotes

Isso me ajudou quando eu precisei usar a mesma parte longa de um regex várias vezes. Não é universal, mas se encaixa no exemplo da pergunta, acredito.


Estou curioso para saber o que será pensado no meu post aqui, mas duvido que seja visto tão longe aqui agora.
Plasmarob

-2
foo = "0.0.0.0"
goo = "here is some other stuff 0.0.0.0" 

puts "success!" if goo =~ /#{foo}/

2
Não, isso dará um erro "true" para "aqui estão outras coisas 070x0! 0", porque os pontos são caracteres curinga de regexp.
Glenn McDonald
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.