Создать регулярное выражение из строки - PullRequest
10 голосов
/ 05 января 2010

Есть ли способ создать регулярное выражение /func:\[sync\] displayPTS/ из строки func:[sync] displayPTS?

История, стоящая за этим вопросом, заключается в том, что у меня есть текстовые строки для поиска в текстовом файле, и я не хочу писать одно и то же снова и снова.

 File.open($f).readlines.reject {|l| not l =~ /"#{string1}"/}
 File.open($f).readlines.reject {|l| not l =~ /"#{string2}"/}

Вместо этого я хочу иметь функцию для выполнения работы:

  def filter string
          #build the reg pattern from string
          File.open($f).readlines.reject {|l| not l =~ pattern}
  end
  filter string1
  filter string2

Ответы [ 4 ]

24 голосов
/ 05 января 2010
s = "func:[sync] displayPTS"
# => "func:[sync] displayPTS"
r = Regexp.new(s)
# => /func:[sync] displayPTS/
r = Regexp.new(Regexp.escape(s))
# => /func:\[sync\]\ displayPTS/
12 голосов
/ 22 февраля 2013

Мне нравится ответ Боба, но только чтобы сэкономить время на клавиатуре:

string = 'func:\[sync] displayPTS'
/#{string}/
3 голосов
/ 05 января 2010

Если строки являются просто строками, вы можете объединить их в одно регулярное выражение, например:

targets = [
  "string1",
  "string2",
].collect do |s|
  Regexp.escape(s)
end.join('|')
targets = Regexp.new(targets)

А потом:

lines = File.readlines('/tmp/bar').reject do |line|
  line !~ target
end

s !~ regexp эквивалентно not s =~ regexp, но легче для чтения.

Избегайте использования File.open без закрытия файла. Файл будет оставаться открытым до тех пор, пока удаленный файловый объект не будет собран сборщиком мусора, что может быть достаточно долго, чтобы в вашей программе не было файловых дескрипторов. Если вам нужно больше, чем просто читать строки, то:

File.open(path) do |file|
  # do stuff with file
end

Ruby закроет файл в конце блока.

Вы также можете подумать, будет ли проще использовать find_all и положительное совпадение, чем отклонение и отрицательное совпадение. Чем меньше негативов должен пройти читатель, тем яснее код:

lines = File.readlines('/tmp/bar').find_all do |line|
  line =~ target
end
0 голосов
/ 05 января 2010

Как насчет использования %r{}:

my_regex = "func:[sync] displayPTS"
File.open($f).readlines.reject { |l| not l =~ %r{#{my_regex}} }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...