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');

如果我的解释不清楚,它应该从这个转变:

富吧巴兹弗雷德
巴尼威尔玛


一二三

对此:

富吧巴兹弗雷德巴尼威尔玛

一二三

(也要注意行尾的尾随空格!)

4

2 回答 2

1

赛德:

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

珀尔:

perl -ne '$a.=$_;END{$_=$a;s/  */ /g;s/[^\n]\n[^\n]/ /g;s/\n\n\n*/\n\n/g;print}' FILENAME
于 2013-02-08T12:43:39.010 回答
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.)

于 2013-04-23T03:05:39.403 回答