是否可以缩短这些正则表达式?

时间:2013-01-22 14:38:17

标签: ruby regex optimization

正如主题所示,是否可以缩短这些正则表达式?我正在使用Ruby 1.9.3

/\n\s+(\w{0,3})[\s&&[^\n]\S]+?([\d\.]+)[\S\s&&[^\n]]+?([\d\.]+)/

和这个

/\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+-*\s+(\d+)\s+(\d+)\s+/

谢谢!

4 个答案:

答案 0 :(得分:2)

  • /\n\s+(\w{0,3})[\s&&[^\n]\S]+?([\d\.]+)[\S\s&&[^\n]]+?([\d\.]+)/

如果我正确理解ruby正则表达式,[\s&&[^\n]\S]表示字符应该是空白字符,而不是非空白字符或不是换行符。由于角色不能同时是空白和非空白角色,您可以将其缩短为[\s&&[^\n]]

您也可以删除括号,(\w{0,3})变为\w{0,3},但如果您稍后在代码中尝试使用这些组中的字符,那么您就不应该这样做。

  • /\s+(\w+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+-*\s+(\d+)\s+(\d+)\s+/

您可以将一些语句\s+\w+(\s+\d+){5}\s+-*(\s+\d+){2}\s+组合在一起,但如果您的代码实际使用这些组来提取信息,这将会导致令人头疼的问题。

答案 1 :(得分:2)

您的目标是拆分固定宽度列的网页吗?

Regexp是一种方式。您可能对固定宽度列方法感兴趣:

uri = URI.parse 'http://www.ida.liu.se/~TDP007/material/seminarie2/weather.txt'
page = uri.read
rows = page.split(/\n/)[9..-3]
rows.each{|r| 
  day, max, mnt = r[0..3].strip, r[4..11].strip, r[12..17].strip
}

答案 2 :(得分:0)

以下内容可能不会更短(如果你计算输入它所需的字符数),但它更具可读性:

arr  = ['(\w+)']     # Match a word
arr += ['(\d+)']*5   # Match five numbers
arr += ['-*']        # ignore dashes
arr += ['(\d+)']*2   # Match two numbers
# All of the above separated with space, plus space before and after.
my_regexp = Regexp.new(([''] + arr + ['']).join('\s+'))

答案 3 :(得分:0)

如果这是您需要处理的唯一文件,那么您可以手动删除不必要的数据,然后逐行读取文件,按空格字符\s+拆分并挑选列。

即使不手动删除不必要的数据,您也可以逐行读取原始文件,按\s+拆分,并测试前几个条目是否为数字。这正是您正在使用正则表达式(测试格式和提取与格式匹配的数据)。

请注意,[\s&&[^\n]\S]表示与\s[^\n]\S相交,这会产生一组:所有空格字符,但是新行。所以我们可以将其重写为[\s&&[^\n]]。但是,[\S\s&&[^\n]]表示相交\S\s[^\n],这会产生一组:所有字符,但是新行。等效的重写是.[^\n],但我怀疑这是你的意思。由于延迟量词,结果对于当前输入仍然是正确的,但它可能不会输入错误。

另一件事.将在字符类中表示文字.,因此[\d.]等同于[\d\.]