首页 > 解决方案 > Javascript Regexp在具有特定结构的文件中查找多个空格

问题描述

我正在寻找一个在 Javascript 正则表达式引擎中工作的正则表达式,它满足以下要求。

我有一个文件,其内容结构如下(框中的文本):

       Column 1        Column 2     Column 3
       _______________________________________________________________________________________________
line  1|Heading 1     Heading 2     Heading 3                                                        |
line  2|      123           456     Quisque imperdiet nibh nec fermentum sollicitudin.               |
line  3|                            Vestibulum eu   elit rutrum, eleifend ligula eu, interdum massa. |
line  4|      789           012     Suspendisse vel   urna vulputate, porta ex ut, varius felis.     |
line  5|                            Praesent a metus faucibus, porttitor magna at, fermentum libero. |
line  6|                                                                                             |
line  7|                                                                                             |
line  8|Heading 1     Heading 2     Heading 3                                                        |
line  9|      123           456     Quisque imperdiet nibh nec fermentum sollicitudin.               |
line 10|                            Vestibulum eu   elit rutrum, eleifend ligula eu, interdum massa. |
line 11|      789           012     Suspendisse vel   urna vulputate, porta ex ut, varius felis.     |
line 12|                            Praesent a metus faucibus, porttitor magna at, fermentum libero. |
       |_____________________________________________________________________________________________|

请注意,该文件不包含制表符,仅包含空格,但我希望将正则表达式扩展为能够处理制表符。

栏目说明:

我想要一个正则表达式,它允许我匹配第三列内容中的额外空格(两个或多个空格、制表符或制表符或空格的任何组合),以便我可以轻松删除它们。目标是在第三列中找到多个空格并将它们替换为单个空格。

我想完全忽略标题行。

我也不想匹配前两列中数字周围的空格。请注意,前两列可能并不总是包含数字。

到目前为止,我能够拼凑的正则表达式如下所示:

/(?=^(?:(?!Heading 1 Heading 2 Heading 3).)*$)([ \t]*[\S]+[^\n]*)[ \t]{2,}/

如果Javascript支持lookbehind我认为这个问题很容易解决,否则我不知道如何解决这个问题。

编辑1:抱歉,我最初的问题并不清楚。我不是在寻找 Javascript 代码,而只是在 Javascript 正则表达式引擎中工作的正则表达式。

此外,我的偏好是单个正则表达式,而不是分多个步骤进行。

编辑 2:规范中添加了更多详细信息。

编辑 3:Lookbehind 断言已被 JavaScript 标准接受,并在撰写此评论时受到一些但并非所有 JavaScript 引擎的支持。请参阅:Javascript:消极的后视等价物?. 这可能通过使用lookbehinds 的单个正则表达式来实现,但我尚未对此进行测试。

非常感谢你的帮助。

标签: javascriptregex

解决方案


我找不到只使用一次替换的解决方案。我认为您需要对字符串进行多次迭代。

我相信这会起作用(/^(?= {20,}| +\d+ +\d+ +\S.* {2,})( +\d+ +\d+ +| +)(\S.*? ) +/gm),但我不确定:

var regex = /^(?= {20,}| +\d+ +\d+ +\S.* {2,})( +\d+ +\d+ +| +)(\S.*? ) +/gm;

const str = `Heading 1     Heading 2     Heading 3
      123           456     Quisque imperdiet nibh nec fermentum sollicitudin.
                            Vestibulum eu   elit rutrum, 5   RANDOM eleifend ligula eu, interdum massa.
      789           012     Suspendisse vel   urna vulputate, porta ex ut, varius felis.
                            Praesent a metus faucibus, porttitor magna at, fermentum libero.


Heading 1     Heading 2     Heading 3
      123           456     Quisque imperdiet nibh nec fermentum sollicitudin.
                            Vestibulum eu   elit rutrum, eleifend ligula eu, interdum massa.
      789           012     Suspendisse vel   urna vulputate, porta ex ut, varius felis.
                            Praesent a metus faucibus, porttitor magna at, fermentum libero.`;
const subst = `$1$2`;

var result = str;

while(regex.test(result))
  result = result.replace(regex, subst)


console.log('Substitution result: \n', result);

旁注

  • 20是一个任意数字,对应于我认为是此处段落的边距;
  • 这个解决方案可能根本不快;
  • 这是一个很好的第一个问题!

推荐阅读