使用正则表达式将行首的空格替换为制表符

10
我希望能够修复文本文件的制表符/空格缩进。
目前,每一行都有随机位置的空格,原因不明。
例如: space tab if -> tab if space tab space tab if -> tab tab if tab tab space if -> tab tab if
等等。
它不应影响第一个单词之后的任何内容,因此只会影响缩进: 因此,tab space if space boolean 应更改为 tab if space boolean 而不是 tab if tab boolean。
正则表达式命令应保持正确数量的选项卡并删除空格。
如果连续4个空格,则应将其转换为制表符:
space space space space -> tab
谢谢您的帮助。如果您能解释一下您的正则表达式是如何工作的,我将非常感激,因为我正在尝试学习如何自己编写正则表达式,而不总是向他人提出请求。
如果您需要更多信息或详细信息,请问我会尽快回复。
我可以逐个解决这个问题,像这样:
对于空格:查找:space*if 替换:if 这仅适用于没有制表符并且第一个单词为 if 的行,因此我会对该行的起始单词执行此操作。
然后我会重复使用 space*\tif
看起来我可以通过这样做,不需要捕获单词:(?: [A-Za-z]) 因此,我只需将 if 替换为此即可,它将运行得更好。

你能在这里链接你的文档吗? - Franklin Satler
你指的是什么类型的“文档”?是指“文本文件”吗?你自己有没有尝试过做这个? - Ken White
@FranklinSatler 不过我可以创建一个示例,文件通常如何附加在SO上? - Aequitas
@KenWhite 是的,它是一个编程代码的文本文件(准确来说是pp格式)。是的,我可以做到,但一次只能处理一个情况,我这样做:查找:空格``*sub 替换为:sub - Aequitas
一个“文档”可以指很多东西(例如,Word .doc 文件、Open Office 文件、HTML 文件等),而这种区别对于您的问题非常重要。如果您指的是“文本文件”,请明确说明。如果您已经努力自己解决了这个问题,请在问题中说明,这样它就不仅仅是一个“这里有个问题,请替我写出解决方案,这样我就什么也不用做了”的帖子。 :-) - Ken White
今天我在Notepad++中替换选定文本中一行开头的两个空格时遇到了麻烦。它似乎一遍又一遍地应用正则表达式,直到所有空格都消失了。在每行开头插入一个标记,比如REPLACEME,然后用“^REPLACEME[ ][ ]”替换为空即可实现我的目标。 - Josiah Yoder
1个回答

13

您可能可以一步完成此操作,但我更倾向于简单的方法。

首先将4个空格翻译为制表符。第一行是匹配项,第二行是替换项。

^(\s*)[ ]{4}(\s*)
$1\t$2

然后将所有剩余的单个空格替换为空。
^(\t*)[ ]+
$1

在这种情况下,您不需要方括号,但是即使在SO的代码格式化中也很难确定是否有空格。第一行搜索行的开头“^”,然后找到任意数量的空格(包括制表符)并将它们放入稍后命名为“$1”的匹配组中,使用“(\ s *)”。中间找到正好四个空格“[ ] {4}”。最后一部分重复匹配组,以防在该侧有制表符或更多空格。由于第二次匹配应该找到剩余的所有空格,所以第二次只查找0个或多个制表符,并将其放入捕获组中,然后查找剩余的空格。由于它每次发现并替换,因此会吞噬所有空格并用制表符替换。

如果在空格之前有一个制表符,这似乎不起作用,对吗? - Aequitas
哇,它能工作了!你能解释一下它是如何工作的吗?:) 谢谢。 - Aequitas
如果您已经使用\s*匹配了所有空格,那么[ ]{4}怎么可能匹配到任何内容呢? - Aequitas
2
根据你的解析器,它可能会。N++ 不像 sed 那样贪心,所以通常可以在不指定匹配应该是最短可能匹配的情况下完成操作。你的直觉是正确的。如果你想非常确定它只匹配最小量的空格直到恰好 4 个空格,请将匹配组设为 (\s*?) - Jeremy Fortune
绝对精彩的答案!我只想强调一下,要想转换所有空格,您应该多次重复“查找和替换”操作。 - Andrii Viazovskyi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接