0

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

13JOHNSON,STEVE

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

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

但事实并非如此。似乎反向引用没有被解释为数字。不过,这很好用:

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

4 回答 4

2

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

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

于 2013-09-30T07:25:17.123 回答
1

你不能那样做。

>> s = '13JOHNSON,STEVE'
=> "13JOHNSON,STEVE"
>> length = s[/^\d{2}/].to_i # s[0,2].to_i
=> 13
>> s[2,length]
=> "JOHNSON,STEVE"
于 2013-09-30T07:26:51.437 回答
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清除那些。

于 2013-09-30T07:38:13.860 回答
0

那这个呢?

a = '13JOHNSON,STEVE'

puts a.match /(?<length>\d{2})(?<name>(.*),(.*))/
于 2013-09-30T07:26:10.707 回答