문제

Here is a Ruby code that explains the issue:

1.8.7 :018 > pattern[:key] = '554 5.7.1.*Service unavailable; Helo command .* blocked using'
 => "554 5.7.1.*Service unavailable; Helo command .* blocked using" 
1.8.7 :019 > line = '554 5.7.1 Service unavailable; Helo command [abc] blocked using dbl'
 => "554 5.7.1 Service unavailable; Helo command [abc] blocked using dbl" 
1.8.7 :020 > line =~ /554 5.7.1.*Service unavailable; Helo command .* blocked using/
 => 0 
1.8.7 :021 > line =~ /pattern[:key]/
 => nil 
1.8.7 :022 > 

Regex works when using directly as a string but doesn't work when I'm using it as a value of hash.

도움이 되었습니까?

해결책

This isn't a Ruby question per se, it's how to construct a regex pattern that accomplishes what you want.

In "regex-ese", /pattern[:key]/ means:

  1. Find pattern.
  2. Following pattern look for one of :, k, e or y.

Ruby doesn't automatically interpolate variables in strings or regex patterns like Perl does, so, instead, we have to mark where the variable is using #{...} inline.

If you're only using /pattern[:key]/ as a pattern, don't bother interpolating it into a pattern. Instead, take the direct path and let Regexp do it for you:

pattern[:key] = 'foo'
Regexp.new(pattern[:key])
=> /foo/

Which is the same result as:

/#{pattern[:key]}/
=> /foo/

but doesn't waste CPU cycles.

Another of your attempts used ., [ and ], which are reserved characters in patterns, used to help define patterns. If you need to use such characters, you can have Ruby's Regexp.escape add \ escape characters appropriately, preserving their normal/literal meaning in the string:

Regexp.escape('5.7.1 [abc]')
=> "5\\.7\\.1\\ \\[abc\\]"

which, in real life is "5\.7\.1\ \[abc\]" (when not being displayed in IRB)

To use that in a regex, use:

Regexp.new(Regexp.escape('5.7.1 [abc]'))
=> /5\.7\.1\ \[abc\]/

다른 팁

line =~ /#{pattern[:key]}/

or...

line =~  Regexp.new pattern[:key]

If you want to escape regex special characters...

line =~ /#{Regexp.quote pattern[:key]}/

Edit: Since you're new to ruby, may I suggest you do this, wherever pattern is defined:

pattern[:key] = Regexp.new '554 5.7.1.*Service unavailable; Helo command .* blocked using'

Then you can simple use the Regexp object stored in pattern

line =~ pattern[:key]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top