正则表达式:高亮显示开头和结尾的换行符

3
我正在尝试编写一个简单的正则表达式,只有当换行符出现在数据的开头或结尾时才会突出显示它们,并保留换行符。在下面的示例中,第1行和第14行都是换行符。这两行是我想要突出显示的,因为它们出现在数据的开头和结尾。

import regex as re
from colorama import Fore, Back

def red(s):
    return Back.RED + s + Back.RESET

with open('/tmp/1.py', 'r') as f:
    data = f.read()

print(
    re.sub(r'(^\n|\n$)', red(r'\1'), data)
)


在这个公式中,数据与上面发布的示例内容相同。
在上面的例子中,这是我得到的结果:

enter image description here

正如你所看到的,红色高亮在第一行缺失,并且跨越整个第14行。我想要的是每个新行字符只出现一次颜色。

^$ 匹配行的开头/结尾,而不是整个内容的开头/结尾。 - Benoît Zu
这可能与终端执行任务的方式有关,请参见此问题 - Wiktor Stribiżew
不知道为什么,但是当脚本开头有两个换行符时它就能正常工作。 - Toto
当我运行你的代码时,无论是使用(^\n|\n$)还是(\A\n|\n\Z),我都会在开头和结尾看到"\x1b[41m\n\x1b[49"。所以我无法复制您的问题。在我的Windows 10平台上,两者都不会产生红线,但这是一个不同的问题。当我在Linux上运行它时,直到输出位于屏幕底部,我仍然看不到红色,然后第一条红线神秘地出现在import语句之后。也许创建围绕换行符的红线的方法有问题。 - Booboo
只是一个旁注:你的替换文本 red(r'\1') 只会在第一次匹配时被评估一次,无论 \1 是什么值,都将用于后续替换。它在你的情况下起作用,因为在你的情况下每个匹配都是相同的,即 \n,因此你可以使用相同的替换。但一般来说,这是错误的做法。更好的方法是:lambda m: red(m[1]),以确保 red 被调用每个匹配。 - Booboo
是的,@Booboo,你说得对。我也无法解释为什么在第一次运行时红线不会显示,但第二次运行会显示。侧面的评论真的很有帮助!没想到可以这样想。 - securisec
3个回答

0

你实际上可以使用你的正则表达式,但是不要使用“multiline”标志。这样它将把整个字符串视为一个整体,从而实现匹配你所需的输出。

^\n|\n$

在这里,您可以看到有两个匹配项。如果您删除前面或后面的换行符,则匹配项将消失。多行标志在正则表达式行的末尾设置或禁用。您也可以在您的语言中执行此操作。

https://regex101.com/r/pSRHPU/2


1
这似乎与我的正则表达式相同,没有分组。我进行分组是为了能够用捕获组替换它本身。 - securisec
我的主要建议是保留正则表达式,不使用多行标志。 - Superluminal
1
啊,是的,我没有使用多行模式。我也尝试了前瞻,但是没有起作用。 - securisec

0

阅读了所有的评论和建议,并结合它们的子集,我终于有了一个可用的版本。对于任何感兴趣的人:

一个问题是我无法在不编写特定于操作系统的检查的情况下解决的是如何为 Windows 添加额外的换行符。

一些被注意到的亮点:

  • 不能给\n上色。所以用空格和换行符替换它。
  • 尚未测试过,但通过去掉组替换,也许也可以将其应用于字节。
  • 可以使用colorama中的init来支持Windows。

import regex as re
from colorama import Back, init

init() # for windows

def red(s):
    return Back.RED + s + Back.RESET

with open('/tmp/1.py', 'r') as f:
    data = f.read()

fist_line = re.sub('\A\n', red(' ')+'\n', data)
last_line = re.sub('\n\Z', '\n'+red(' '), fist_line)
print(last_line)

OSX/Linux

enter image description here

Windows

enter image description here


-1

1
我肯定从你的回答中学到了一些东西!但是,它并没有完全解决需求。如果你运行代码,你会注意到它不是突出显示第一行,而是第二行的末尾。 - securisec

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