这个RegEx有什么问题?

时间:2011-04-16 21:15:51

标签: ruby regex

我正在尝试在一个小的ruby脚本中实现它,并在http://www.rubular.com/上测试它,它在那里工作得很好。不确定为什么它在实际脚本中没有表现。

RegEx: /(动作|链接|声音|按钮|符号)|(0. \ d {8})|(\ s \ d {1} \ s)|(\ d {10} \ S)/

反对的文字:

试用ID:1 |试用类型:动作|特技? 1 点击时间:0.87913100 1302969732

试用ID:7 |试用类型:按钮|特技? 0 点击时间:0.19817800 1302987043

等。等

我想要抓住的内容:只有数字,以及“试用类型”之后的单个字词。因此,对于示例的第一行,我只想要返回“1 motion 1 0.87913100 1302969732”。我还希望在每次试验的第一个数字之前保留空格。

我的短红宝石脚本

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 个答案:

答案 0 :(得分:4)

您想使用String#scan

 matchdata = contents.scan(regex)

同样@Mike Penington是正确的,如果你做得对,你不应该做if match != nil。你也必须清理你的正则表达式。正则表达式中的管道字符是一个特殊字符,表示与左侧或右侧匹配,并且您具有必须转义的管道字符。

答案 1 :(得分:3)

你需要转义正则表达式中的文字管道,填写其他缺少的文字(如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 :(得分:2)

如果您知道数据遵循特定模式,则可以在正则表达式中遵循该模式,并使用( )选择所需的部分。

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

您之前对数据的了解越多,您就越具体地制作正则表达式。 如果您看到数据中存在某些变化,并且正则表达式无法匹配,那么只需放松模式:

  • 如果Trail ID,Trail ID可能包含小数点,请使用[\.\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]+)/

答案 3 :(得分:1)

这是其中一个尝试大型正则表达式中的所有内容的时间之一会让您的工作变得过于艰难。简化事情:

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

正则表达式模式很强大,但人们认为在一条大线上做所有事情都是大胆的。你必须权衡这一点,首先将正则表达式放在一起所需的增加的工作,并且如果稍后要解析的文本中的某些内容发生变化,请保持它。