2015-04-23 39 views
0

我有一個輸入字符串,像這樣的:解析和轉換文本的文章繁殖

如果你{決定|計劃|願望} {去|要去}到{露營|擁有室外 休息|釣魚|狩獵},你{可能需要|只需要|可以使用}睡覺 包[PRODUCT NAME]。 {它|此睡袋} {用於 [SEASON]和{縫製|}由[TYPE] {型|形狀因子}是理想的}。

現在,我需要做的這件事情:

  1. 認沽值代入方括號(EX [產品名稱]成爲堅硬耐磨 山)
  2. 採取從大括號和隨機單詞。粘貼(前 {決定|計劃|願望}成爲計劃}

因此,輸出字符串會是這樣一個:

如果你想去釣魚,你可能會喜歡睡覺 硬包山。這款睡袋適用於冬季的 ,採用繭形設計。

我知道如何解決#1問題,但是對問題#2有想法。 此外,還可以嵌套方括號,例如:{some word | {some word2 | {some word3 | some word5}} | some word4}。

所以我需要一個Ruby的正則表達式,或者可能是另一種方法來解決這個問題。

+0

http://stackoverflow.com/questions/6331065/matching-balanced-parenthesis-in-ruby-using-recursive-regular-expressions-like-p – 2015-04-23 04:42:57

+0

@CarySwoveland完成。 – tchrist

回答

1

想這是我們的文字:

text = 

「如果你{決定|擬|願望} {去|要去}到{露營|有戶外休息|釣魚|獵},您{可能喜歡|需要|只需要|可以使用}睡袋[產品名稱]。 {它|這個睡袋} {用於[SEASON]和{設計|縫製] {TYPE] {type | form-factor}是理想的。 {它是| {真的| {並非如此}}}絕對是一個很棒的包。'

注意我在最後一句中添加了一些嵌套的大括號。

首先,獲得替代由哈希規定:

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) 

返回:

「如果你{決定|計劃|願望} {到到{野營|有戶外休息|釣魚|狩獵},你{可能需要|只需要|可以使用}睡袋Hard Wear Mountain。{It | This sleeping bag} {is intended | is ideal}用於秋天和由...縫製薪酬低的工人{type | form-factor}。 {是| {真| {不是那麼|所有}} |肯定}大袋「

每串s = [...]h[s]如果h有一個關鍵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 

返回:

「如果你決定要到釣魚,你需要睡袋Hard Hard Mountain。這款睡袋適用於秋季,並且由低薪工人縫製。這是一個很好的包「

這裏的想法是做一個替換序列,每次形式爲'{...|...|... }'的字符串,其中...的不包含左括號,因此不包含嵌套。block顯示的步驟,下面顯示的順序隨機更換(當然這可能比上面我所不同)

第一輪替換

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

現在new等於:

「如果你打算去打獵,你只需要睡袋Hard Hard Mountain。它是秋季和理想的低薪工人類型。 {是| {真|所有} |肯定}大袋「

請注意:所有非嵌套撐塊已經解決,並嵌套塊:

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

一直由一個在嵌套級別降低:

{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現在等於:

「如果你計劃要去打獵,你只需要睡袋Hard Wear Mountain,適合秋季和低薪工作者製作{這是一款非常棒的包。

第三輪更換

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 
+0

非常感謝您的回覆。關於替換的一個問題 - 它可以與嵌套括號一樣嗎?此外,現在測試你的代碼,但是任何時候我運行循環,它都會返回相同的輸出字符串。爲什麼他們不是隨機的?問候。 –

+0

在循環遍歷隨機替換時,我進行了賦值'str = s'。我懷疑我的變量'str'的​​重用可能會解釋爲什麼你繼續得到相同的輸出字符串。我相信如果你沒有每次重新初始化'str',就會發生這種情況,因爲它會以一個不包含括號塊的字符串替換。你會看到我已經改變了代碼,以便在最初計算之後不再修改'str'。讓我知道是否解決了這個問題。我會在早上考慮嵌套括號。你能舉一個你如何打算使用它們的例子嗎? –

0

下面的正則表達式將捕獲文本,也爲嵌套情況:

(?<=[|{])([\w\s]+?)(?=[}|])

然後,您可以決定比賽的數量和選擇隨機指數小於比賽組大小。