【问题标题】:Collapse whitespace except multiple blank lines using regular expressions使用正则表达式折叠除多个空行之外的空格
【发布时间】:2013-02-08 12:32:47
【问题描述】:

过去我不止一次想知道格式化文本块的问题,以便所有运行的空白都“折叠”到一个空格中,除了应该保留段落 - 这意味着所有运行的空白行折叠成单个空行,但不折叠成一个空格。

空白行当然是两个行尾字符(通常是回车或换行或两者),没有任何中间的非空白字符。 (可能还有其他空格,例如空格或制表符)。

这肯定是一个相当普遍的问题,虽然解决起来并不难,但我总是对我的解决方案不满意,这些解决方案缺乏优雅或存在漏洞。当然有一种优雅的表达方式可以做到这一点。

我将把它开放给所有正则表达式风格,因为我想至少在 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');

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

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


一二三

到这里:

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

一二三

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

【问题讨论】:

    标签: regex whitespace text-formatting blank-line


    【解决方案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
    

    【讨论】:

    • 目前我在 Windows 上并且无法访问 sed,我也不知道 sed,所以我无法自己解析它。如果单行是 Windows 友好的,我会尝试 Perl...
    • 在 Windows 上,Perl 需要 " 而不是 ',即使进行了更改,我也会丢失所有段落格式(双空行)。
    • 啊。在您的示例中,您将四重换行符更改为单个换行符。您能否生成一个对我来说更具描述性的示例输入和输出? (以及段落格式)当我测试时,我的两个程序都可以使用原始帖子中发布的示例。
    • 我的两个程序都应该将两个或多个连续的换行符变成一个换行符。
    • 对不起!我想也许在我做对之后,Stack Exchange 渲染的降价或其他部分改变了它。让我调查一下……现在修复。它应该将单个换行符变成一个空格,将两个或多个连续的换行符变成正好两个换行符。
    【解决方案2】:

    我刚刚又遇到了这个问题。这次我使用的是 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。)

    【讨论】:

      猜你喜欢
      • 2014-09-04
      • 1970-01-01
      • 1970-01-01
      • 2021-04-10
      • 2023-04-08
      • 2017-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多