2013-02-08 143 views
0

過去我不止一次地想過格式化文本塊的問題,以便將所有空白運行「摺疊」爲一個空格,但段落應該是保存 - 意味着所有空行的運行都會摺疊爲單個空行,但不會摺疊爲空格。使用正則表達式摺疊除空白行之外的空白

空白行當然是兩個行尾字符(通常是回車符或換行符或兩者),沒有任何中間非空白字符。 (雖然可能有其他空格,例如空格或製表符)。

這確實是一個很常見的問題,雖然不難解決,但我總是對我的解決方案不滿意,因爲這些解決方案缺乏優雅或留下漏洞。當然,有一個優雅的表達方式來做到這一點。

由於我至少希望在Perl,Vim和JavaScript中使用它,所以我將它放到了所有的正則表達式中。這是我最近在node.js中做的懶惰嘗試,這個漏洞顯然是魔術詞。這也可能是非常典型的,我用::

text = text.replace(/\r?\n(?:\s*\r?\n)+/g, '_SomeMagicWord_'); 
text = text.replace(/\s\s+/gm, ' '); 
text = text.replace(/_SomeMagicWord_/g, '\r\n\r\n'); 

如果我的解釋並不清楚應該從這次改造不理想的解決方案:

富酒吧巴茲
弗雷德·巴尼威爾瑪


一二三

這樣:

富酒吧巴茲弗雷德·巴尼威爾瑪

一二三

(!當心在線路的兩端也尾隨空白)

回答

1

的sed:

sed -n 'H;$g;$s/[^\n]\n[^\n]/ /g;$s/\n\n\n*/\n\n/g;$s/ */ /g;$s/^\n//;$p' FILENAME 

Perl:

perl -ne '$a.=$_;END{$_=$a;s/ */ /g;s/[^\n]\n[^\n]/ /g;s/\n\n\n*/\n\n/g;print}' FILENAME 
+0

目前我在Windows上並沒有訪問sed,我也不知道sed,所以我不能自己解析。我會嘗試一個Perl,但如果單線程是Windows友好的... – hippietrail 2013-02-08 13:04:38

+0

在Windows上,Pe​​rl需要使用'''而不是''',即使有這種變化,我正在失去al段落格式化(雙空行) 。 – hippietrail 2013-02-08 13:08:47

+1

在你的例子中,你將四行換行變成了一個換行符,你能爲我提供一個更具描述性的例子輸入和輸出嗎?(也有段落格式)當我測試時,我的兩個程序都可以 – protist 2013-02-08 13:12:28

0

我剛剛就這個問題再次提出。這一次,我使用Node.js的,我覺得我想出了一個漂亮的表現力的解決方案:

txt = txt.replace(/\s+/g, function (ws) { 
    return /\n.*\n/.test(ws) ? '\n\n' : ' '; 
}); 

txt = txt.replace(/(^(|\n\n)|(|\n\n)$)/g, ''); 

,第一部分考慮了文本的空白和檢查的每個運行,如果有在其中至少兩個換行符。如果是這樣,它會崩潰到段落中斷(連續兩次換行而沒有其他)。否則它會崩潰到一個空間。

第二部分修剪文本開始和結尾的任何剩餘空白,在這一點上,每個空白僅可能是單個空格或一對換行符。 (我唯一的限制是由JavaScript的\s強加的,它不符合所有的Unicode空格代碼點;並且可選地輸出MS樣式的換行符,\r\n而不是\n。)