-1

正如主题所暗示的那样,是否可以使这些正则表达式更短?我正在使用 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

4 回答 4

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

如果我正确理解了 ruby​​ 正则表达式,则[\s&&[^\n]\S]意味着一个字符应该是一个空白字符并且是一个非空白字符或不是换行符。由于一个字符不能既是空白字符又是非空白字符,您可以将其缩短为[\s&&[^\n]].

您也可以删除括号,(\w{0,3})become \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+但是如果您的代码实际上使用这些组来提取信息,这又会引起头痛。

于 2013-01-22T14:55:56.050 回答
2

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

正则表达式是一种方式。您可能对固定宽度列的方法感兴趣:

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
}
于 2013-01-22T15:35:37.057 回答
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+'))
于 2013-01-22T15:10:57.147 回答
0

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

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

请注意,这[\s&&[^\n]\S]意味着相交\sand [^\n]\S,这会导致 set: all space characters but new line。所以我们可以将其重写为[\s&&[^\n]]. 但是,[\S\s&&[^\n]]表示相交\S\sand [^\n],这会导致 set: all characters but new line。等效的重写是.or [^\n],但我怀疑这就是你的意思。由于惰性量词,结果对于当前输入仍然是正确的,但对于错误的输入可能不是。

另一件事是在字符类中.表示文字,因此相当于..[\d.][\d\.]

于 2013-01-22T15:14:53.563 回答