2012-05-10 64 views
6

Chcę użyć grep z ciągiem jako wzór regex. Jak mogę to zrobić?Ruby grep z argumentem ciągu znaków

Przykład:

myArray.grep(/asd/i) #Works perfectly. 

ale chcę przygotować pierwsze moje oświadczenie

searchString = '/asd/i' 
myArray.grep(searchString) # Fails 

W jaki sposób można to osiągnąć? Potrzebuję przygotowanego ciągu, ponieważ przechodzi on do algorytmu wyszukiwania, a zapytanie będzie się zmieniać przy każdym żądaniu. Dzięki.

+0

Kiedy mówiłem, że grep z argumentem łańcuchowym nie działa, nie daje błędu, ale nic nie zwraca. – gkaykck

+0

Mam zapytanie od użytkownika, które jest ciągiem znaków – gkaykck

+0

To nie jest proste pytanie. Zobacz [to pytanie] (http://stackoverflow.com/questions/6669425/convert-a-regular-expression-in-a-string-to-a-regexp-object-in-ruby) – Flexoid

Odpowiedz

9

Wyrażenia regularne wsparcie interpolacji, podobnie jak ciągi:

var = "hello" 
re = /#{var}/i 
p re #=> /hello/i 
+0

Pamiętaj, że możesz chcieć uciec wartość przed interpolacją, szczególnie jeśli jest dostarczana przez niezaufanego użytkownika: '/ # {Regexp.escape (user_provided_string)}/i' lub 'Regexp.new (Regexp.escape (user_provided_string)," i ")'. To na przykład potraktuje "." jako dosłowny "."znak, a nie jak" dowolny znak ". Jako krótki, ale tajemniczy sposób na ucieczkę ciągu znaków * i * przekształcenia go w wyrażenie regularne, można wykonać' Regexp.union (user_provided_string) '. –

1

Spróbuj tego:

searchString = /asd/i 
myArray.grep(searchString) 
+0

Nie mogę , mam ciąg pochodzi od użytkownika, w jaki sposób można scalić ten ciąg z/asd/i? – gkaykck

4

Mając coś w cudzysłowie nie jest taka sama jak w samej rzeczy. /a/i to Regexp, "https://stackoverflow.com/a/i" to ciąg znaków. Aby skonstruować wyrażenie regularne z łańcucha to zrobić:

r = Regexp.new str 
myArray.grep(r) 
+0

Regexp.new ('/ asd/i') zwraca wyrażenie regularne (? -mix: \/asd \/i)? – gkaykck

+0

@gkaykck wynik nie jest taki sam na moim komputerze, nadal chciałbym podkreślić, że regexp nie jest ciągiem znaków. Po prostu pokazuję ci, jak skonstruować wyrażenie regularne z ciągu znaków. W powyższym przykładzie, jeśli str = "/ u /", wtedy r stanie się/\/u \ // co nie jest tym, czego chcesz, wierzę, że możesz wymyślić, jak zrobić to, co chcesz –

1

Edit:

znalazłem lepszy sposób

myString = "Hello World!" 
puts "Hello World!" 
puts "Enter word to search" 
input_search = gets.chomp 
puts "Search insensitive? y/n" 

answer = gets.chomp 

if answer == "y" 
    ignore = "Regexp::IGNORECASE" 
else 
    ignore = false 
end 

puts myString.lines.grep(Regexp.new(input_search, ignore)) 

Moja stara Odpowiedź poniżej:

Spróbuj czyniąc to przypadek lub if przechodząc jeśli chcą niewrażliwe wyszukiwanie włączyć lub wyłączyć, etc

myString = "Hello World!" 
puts "Enter word to search" 
input_search = gets.chomp 
puts "Search insensitive? y/n" 
case gets.chomp 
    when "y" 
    puts myString.lines.grep(Regexp.new(/#{input_search}/i)) 
    when "n" 
    puts myString.lines.grep(Regexp.new(/#{input_search}/)) 
end 
0

'/ USA/i' jest String. Dlaczego nie sprawić by Regrexp? Jeśli trzeba iść z String do regexp jeden ze sposobów, aby to zrobić jest stworzenie nowego obiektu RegExp:

>> re = Regexp.new('/asd/i') 
=> /\/asd\/i/ 
>> re = Regexp.new("asd", "i") 
=> /asd/i 

Więc może,

>> str = gets.chomp #user inputs 
=> "Hello World" 
re = Regexp.new(str, "i") 
=> /Hello World/i 

jest to, czego szukasz.

Ale ogólnie nie sądzę, że można po prostu "użyć ciągu jako wzorca regexp", choć jestem początkującym i może się mylić.

Powiązane problemy