Что не так с этим RegEx? - PullRequest
1 голос
/ 17 апреля 2011

Я пытаюсь реализовать это в небольшом скрипте ruby ​​и протестировал его на http://www.rubular.com/,, где он работал отлично.Не уверен, почему он не работает в реальном сценарии.

RegEx: / (движение | ссылки | звук | кнопка | символ) | (0. \ d {8}) | (\ s \ d {1} \ s) | (\ d {10} \ s) /

Текст, против которого он выступает:

Идентификатор испытания: 1 |Тип испытания: движение |Trick?1 Время щелчка: 0,87913100 1302969732

Идентификатор пробной версии: 7 |Тип испытания: кнопка |Trick?0 Время щелчка: 0,19817800 1302987043

и т. Д.и т. д.

То, что я пытаюсь схватить: Только цифры и одно слово после «Тип испытания».Поэтому для первой строки примера я бы хотел, чтобы возвращалось только «1 движение 1 0,87913100 1302969732».Я также хочу оставить пробел перед первым числом в каждом испытании.

Мой короткий скрипт ruby ​​:

File.open('log.txt', 'r') do |file|
  contents = file.readlines.to_s
  regex = Regexp.new(/(motion|links|sound|button|symbol)|(0\.\d{8})|(\s\d{1}\s)|(\d{10}\s)/)
  matchdata = regex.match(contents).to_a
  matchdata.each do |match|
    if match != nil
      puts match
    end
  end
end

Он выводит только два "1", хотя,Хм ... Я знаю, что он правильно читает содержимое файла, и когда я попробовал альтернативное регулярное выражение, он работал нормально.

Спасибо за любую помощь, которую я получил здесь !!:)

Ответы [ 4 ]

4 голосов
/ 17 апреля 2011

Вы хотите использовать String # scan

 matchdata = contents.scan(regex)

Также @Mike Penington верен, вам не нужно делать if match != nil, если вы делаете это правильно. Вы также должны очистить свое регулярное выражение. Символ трубы в регулярном выражении - это специальный символ, обозначающий совпадение левой стороны ИЛИ правой стороны, и у вас есть символ литеральной трубы, который вы должны экранировать.

3 голосов
/ 17 апреля 2011

Вам необходимо экранировать литеральные каналы внутри регулярного выражения, заполнять другие недостающие литералы (например, Trick, \ ?, Click \ sTime:, удалять некоторые пробелы и т. Д.) И вставлять пробелы регулярных выражений, где это необходимо. .. т.е.

regex = Regexp.new(/(motion|links|sound|button|symbol)\s\|\sTrick\?\s*\d\s*Click\s+Time:\s+(0\.\d{,8})\s(\d{10}))/)

РЕДАКТИРОВАТЬ: исправление вложенности круглых скобок в оригинале

2 голосов
/ 17 апреля 2011

Если вы знаете, что данные следуют определенному шаблону, вы можете просто следовать этому шаблону в регулярном выражении и выбрать нужные вам части с помощью ( ).

/Trial ID: (\d+) \| Trial Type: (\w+) \| Trick\? (\d+) Click Time: ([\.\d]+) ([\.\d]+)/

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

  • Если идентификатор следа, идентификатор следа может содержать десятичную точку, используйте [\.\d]+ вместо\d+.
  • Если пробел может быть больше одного, заменить его на []+
  • Если пробел может быть табуляцией или может отсутствовать, используйте \s* или[ \t]*.
  • Если часть Trial ID: может выглядеть как другая фраза, замените ее на .*?,

и т. Д.

ЕслиВы не уверены, сколько пробелов / табуляции появляется, используйте это:

/Trial\s*ID:\s*(\d+)\s*\|\s*Trial\s*Type:\s*(\w+)\s*\|\s*Trick\?\s*(\d+)\s*Click\s*Time:\s*([\.\d]+)\s+([\.\d]+)/
1 голос
/ 17 апреля 2011

Это один из тех случаев, когда попытки использовать все в большом регулярном выражении заставляют вас слишком усердно работать.Упростите вещи:

ary = [
  'Trial ID: 1 | Trial Type: motion | Trick? 1 Click Time: 0.87913100 1302969732',
  'Trial ID: 7 | Trial Type: button | Trick? 0 Click Time: 0.19817800 1302987043'
]

ary.each do |li|
  numbers = li.scan(/[\d.]+/)
  trial_type = li[/Trial Type: (\w+)/, 1]

  puts "%d %s %d %f %d\n" % [numbers.first, trial_type, *numbers[1 .. -1]]
end
# >> 1 motion 1 0.879131 1302969732
# >> 7 button 0 0.198178 1302987043

Шаблоны регулярных выражений являются мощными, но люди думают, что делать все в одну большую строку - это мужество.Вы должны взвесить это, увеличив объем работы, необходимой для того, чтобы сначала собрать регулярное выражение, а также сохранить его, если что-то изменится в последующем анализе текста.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...