过去不止一次我想知道格式化文本块的问题,以便所有空格的运行都“折叠”到一个空格中,除了段落应该被保存 - 意味着所有空白行的运行被折叠成单个空白行,但没有折叠成一个空格。
空白行当然是两个行尾字符(通常是回车符或换行符或两者),没有任何插入的非空白字符。 (可能还有其他空格,例如空格或制表符)。
这肯定是一个非常普遍的问题,虽然不难解决,但我总是对我的解决方案感到不满,因为我的解决方案缺乏优雅或留下漏洞。当然,有一种优雅的表达方式来做到这一点。
因为我想至少在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');
如果我的解释不清楚,它应该改变:
foo bar baz
弗雷德巴尼威尔马
一二三
到此:
foo bar baz fred barney wilma
一二三
(注意线末端的尾随空格!)
答案 0 :(得分: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
答案 1 :(得分: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
。)