使用正则表达式反向引用值作为正则表达式中的数值

时间:2013-09-30 07:21:18

标签: ruby regex

我有一个包含可变长度部分的字符串。该部分的长度在该部分的内容之前。例如,在字符串中:

13JOHNSON,STEVE

前2个字符定义内容长度(13),后跟实际内容。我希望能够使用带有反向引用的命名捕获组来解析它,但我不确定它是否可行。我希望这会奏效:

(?<length>\d{2})(?<name>.{\k<length>})

但事实并非如此。似乎反向引用不被解释为数字。这样可以正常工作:

(?<length>\d{2})(?<name>.{13})

4 个答案:

答案 0 :(得分:2)

不,当然不行。提取第一个数字后,需要重新编译正则表达式。

我建议你使用两种不同的表达方式: 第一个提取数字,第二个提取基于第一个提取的数字的文本。

答案 1 :(得分:1)

你做不到。

>> s = '13JOHNSON,STEVE'
=> "13JOHNSON,STEVE"
>> length = s[/^\d{2}/].to_i # s[0,2].to_i
=> 13
>> s[2,length]
=> "JOHNSON,STEVE"

答案 2 :(得分:1)

这看起来好像你正在努力追求这一点。我怀疑样本字符串并不像你说的那么简单,基于:

  

我有一个包含可变长度部分的字符串。该部分的长度在该部分的内容之前。

相反,我会使用类似的东西:

str = "13JOHNSON,STEVE 08Blow,Joe 10Smith,John" 
str.scan(/\d{2}(\S+)/).flatten # => ["JOHNSON,STEVE", "Blow,Joe", "Smith,John"]

如果可以准确地分割字符串,那就是:

str.split.map{ |s| s[2..-1] }  # => ["JOHNSON,STEVE", "Blow,Joe", "Smith,John"]

如果你只有长度字节后跟字符串,那么它们之间没有任何东西可以这样工作:

offset = 0
str.delete!(' ') # => "13JOHNSON,STEVE08Blow,Joe10Smith,John"
str.scan(/\d+/).map{ |l| s = str[offset + 2, l.to_i]; offset += 2 + l.to_i ; s } 
# => ["JOHNSON,STEVE", "Blow,Joe", "Smith,John"]

  如果名称中包含数字,则

将无效 - tihom

str = "13JOHNSON,STEVE 08Blow,Joe 10Smith,John 1012345,7890" 
str.scan(/\d{2}(\S+)/).flatten # => ["JOHNSON,STEVE", "Blow,Joe", "Smith,John", "12345,7890"]
str.split.map{ |s| s[2..-1] }  # => ["JOHNSON,STEVE", "Blow,Joe", "Smith,John", "12345,7890"]

稍作修改,稍加一点,它将继续正常使用不包含分隔符的字符串:

str.delete!(' ') # => "13JOHNSON,STEVE08Blow,Joe10Smith,John1012345,7890"

offset = 0
str.scan(/\d{2}/).map{ |l| s = str[offset + 2, l.to_i]; offset += 2 + l.to_i ; s }.compact 
# => ["JOHNSON,STEVE", "Blow,Joe", "Smith,John", "12345,7890"]

\d{2}以两人一组的形式抓取数字。对于数字是两个字符的前导长度值的名称,这是根据OPs样本,正确的事情发生。对于实数数字“名称”,将返回几个误报,这将返回nil个值。 compact清除那些。

答案 3 :(得分:0)

这个怎么样?

a = '13JOHNSON,STEVE'

puts a.match /(?<length>\d{2})(?<name>(.*),(.*))/