我试图通过在子字符串的每个部分中插入连字符来使UUID成为正确符合的UUID。
test = "CB13DBB20A9945CC86F11914C979C761"
#The first one will return '----' so essentially the $1 to $5 are returned as emptys
test.sub(/(\h{8})(\h{4})(\h{4})(\h{4})(\h{12})/, "#{$1}-#{$2}-#{$3}-#{$4}-#{$5}")
#Returns the ideal result of CB13DBB2-0A99-45CC-86F1-1914C979C761
test.sub(/(\h{8})(\h{4})(\h{4})(\h{4})(\h{12})/, "#{$1}-#{$2}-#{$3}-#{$4}-#{$5}")
正如您所看到的,第一次运行该函数不起作用,但第二次运行。任何想法都会很棒。作为附加信息,
test.match(/(\h{8})(\h{4})(\h{4})(\h{4})(\h{12})/){|m| "#{$1}-#{$2}-#{$3}-#{$4}-#{$5}"}
将首次使用。单引号和双引号不会影响任何内容。
答案 0 :(得分:4)
虽然这可以使用正则表达式完成,但我会选择子字符串:
require 'pp'
uuid = 'CB13DBB20A9945CC86F11914C979C761'
pp [uuid[0, 8], uuid[8, 4], uuid[12, 4], uuid[16, 4], uuid[20, 12]]
# => ["CB13DBB2", "0A99", "45CC", "86F1", "1914C979C761"]
puts [
uuid[0, 8], uuid[8, 4], uuid[12, 4], uuid[16, 4], uuid[20, 12]
].join('-')
# => CB13DBB2-0A99-45CC-86F1-1914C979C761
因为在编写代码时使用偏移量和长度可能是一件苦差事,所以这里是使用unpack
只有长度的替代品:
lengths = [8, 4, 4, 4, 12]
uuid.unpack(lengths.map{ |l| "a#{ l }" }.join).join('-')
# => "CB13DBB2-0A99-45CC-86F1-1914C979C761"
答案 1 :(得分:3)
像这样引用模式匹配。
test.sub(/(\h{8})(\h{4})(\h{4})(\h{4})(\h{12})/, '\1-\2-\3-\4-\5')
您在Ruby Docs中解释了这种行为的原因:
如果replacement是一个String,它将替换匹配的文本。 它可能包含对格式\ d的模式捕获组的反向引用,其中d是组号,或\ k,其中n是组名。如果它是双引号字符串,则两个反向引用都必须以额外的反斜杠开头。 但是,在替换中,特殊匹配变量(例如& $)不会引用当前匹配。
答案 2 :(得分:1)
在您的示例中,$ 1 ... $ 5替换为字符串替换之前。
如果您想在替换期间对它们进行评估,请改为使用块形式:
test.sub(/(\h{8})(\h{4})(\h{4})(\h{4})(\h{12})/) { "#{$1}-#{$2}-#{$3}-#{$4}-#{$5}" }
答案 3 :(得分:0)
FWIW,Ruby有SecureRandom来提供uuid的
require 'securerandom'
p SecureRandom.uuid #"dd1f58f8-8c42-47e0-9c08-a8d5c191c9c3"
使用String#unpack
test = "CB13DBB20A9945CC86F11914C979C761"
p test.unpack("A8A4A4A4A8").join('-') #"CB13DBB2-0A99-45CC-86F1-1914C979"