解析和转换文章复制的文本



我有一个这样的输入字符串:

如果你{决定|计划|愿望} {去|

去}到{露营|有户外 休息|钓鱼|打猎},你{可能喜欢|需要|只是需要|可以使用}睡觉 袋 [产品名称]。{它|这个睡袋}{是打算|是理想的} [SEASON] 和 {designed|sewed|made} by [TYPE] {type|form-factor}。

现在,我需要做这些事情:

  1. 将值放入方括号中(例如,[产品名称] 变为硬磨损 山)
  2. 从大括号中随机取出一个单词并粘贴它(例如。 {已决定|计划|愿望} 成为计划}

因此,输出字符串将如下所示:

如果你想去钓鱼,你可能喜欢睡觉 包硬穿山。这款睡袋非常适合 冬季,由茧外形设计。

我知道如何解决#1问题,但对问题#2有想法。 此外,还可以有嵌套的方括号,例如:{某些单词|{一些词2|{一些单词3|一些单词5}}|一些单词4}。

所以我需要一个 Ruby 的正则表达式,或者另一种方法来解决这个问题。

假设这是我们的文本:

text =

'如果你{决定|计划|愿望}{去|去}{露营|户外休息|钓鱼|狩猎},你{可能喜欢|需要|只需要|可以使用}睡袋[产品名称]。{它|这个睡袋} {是打算|是理想的} [季节] 和 {设计|缝制|制造} 由 [类型] {类型|外形}.{它是|{真的|{不是这样|所有这些}}|当然}是一个很棒的袋子。

请注意,我在最后一句中添加了一些嵌套的大括号。

首先,获取由哈希指定的替换:

h = { '[PRODUCT NAME]'=>'Hard Wear Mountain',
'[SEASON]'=>'fall',
'[TYPE]'=>'underpaid workers' }

如下:

r = /
[  # match a left bracket
.+? # match >= 1 characters non-greedily (stop at 1st right bracket)
]  # match right bracket
/x
str = text.gsub(r,h)

返回:

"如果你{决定|计划|愿望}{去|去}{露营|户外休息|钓鱼|狩猎},你{可能喜欢|需要|只需要|可能使用}睡袋硬穿山。{它|这个睡袋}{是打算|是理想的}秋天和{设计|缝制|制造}由低薪工人{类型|外形}。{它是|{真的|{不是这样|所有这些}}|当然}是一个很棒的袋子。

如果每个字符串s = [...]都有一个键s,则hh[s]替换;否则不进行替换。

现在进行更换,从内部{...|...|...}开始,然后向外工作,直到不再进行更换:

old = str  
loop do
new = old.gsub(/{[^{]+?(?:|[^{}]+?)+}/) do |s|
a = s[1..-2].split('|')
a[rand(a.size)]
end
break if new==old
old=new 
end
old 

返回:

"如果你决定去钓鱼,你需要睡袋硬穿山。这款睡袋专为秋季使用,由低薪工人缝制。这是一个很棒的袋子。

这里的想法是做一系列替换,每次字符串的形式'{...|...|... }'其中...不包含左括号,因此不包含嵌套块。为了显示这些步骤,下面显示了顺序随机替换(当然可能与我上面所说的不同)。

第一轮替换

str # as above
old = str  
new = old.gsub(/{[^{]+?(?:|[^{}]+?)+}/) do |s|
a = s[1..-2].split('|')
a[rand(a.size)]
end
new==old #=> false 

现在new等于:

"如果你打算去打猎,你只需要睡袋硬穿山。它是秋季的理想选择,由低薪工人类型制造。{它是|{真的|所有这些}|当然}是一个很棒的包。

请注意,所有非嵌套大括号块都已解析,并且嵌套块:

{It is|{really|{not so|all that}}|certainly}

嵌套级别降低了 1:

{It is|{really|all that}|certainly}

由于{not so|all that}已被all that.此块中的随机替换按如下方式完成:

s0 = '{not so|all that}'
s1 = s0[1..-2]
#=> "not so|all that" 
a  = s1.split('|')
#=> ["not so", "all that"] 
a[rand(a.size)]
#=> a[rand(2)] => a[1] => "all that"

第二轮替换

old=new 
new = old.gsub(/{[^{]+?(?:|[^{}]+?)+}/) do |s|
a = s[1..-2].split('|')
a[rand(a.size)]
end
new==old #=> false 

new现在等于:

"如果你打算去打猎,你只需要睡袋硬穿山。它是秋季的理想选择,由低薪工人类型制造。{这是|所有|当然}一个伟大的袋子。

第三轮替换

old=new 
new = old.gsub(/{[^{]+?(?:|[^{}]+?)+}/) do |s|
a = s[1..-2].split('|')
a[rand(a.size)]
end
new==old #=> false 

new现在等于:

"如果你打算去打猎,你只需要睡袋硬穿山。它是秋季的理想选择,由低薪工人类型制造。当然是一个很棒的包。

我们现在已经完成了,但直到我们再次尝试并找到那个new == old #=> true才会知道。

第四轮替换

old=new 
new = old.gsub(/{[^{]+?(?:|[^{}]+?)+}/) do |s|
a = s[1..-2].split('|')
a[rand(a.size)]
end
new==old #=> true

以下正则表达式将捕获文本,也适用于嵌套情况:

(?<=[|{])([ws]+?)(?=[}|])

然后,您可以确定匹配项的数量,并选择小于匹配组大小的随机索引。

相关内容

  • 没有找到相关文章

最新更新