如何匹配不在4的倍数中的空格?
我正在用notepad++重新格式化一个Python脚本,但有些行的缩进不是4个(或者8、12、16等)空格。
所以我需要找到连续的开头空格(也就是每行开头的缩进),这些空格不是4的倍数,也就是说,空格的数量是1、2、3、5、6、7、9、10、11等等。
例如:
>>> a = 1 # match this, as there're 3 spaces at the beginning
>>> b = a # match this too, as indent by 7 spaces
>>> c = 2 # but not this, since it's indented exactly by 4 spaces
>>> d = c # not this either, since indented by 8 spaces
我能用类似这样的方式找到4的倍数的空格:
^( {16}| {12}| {8}| {4})
然后我试着用类似这样的方式找到相反的情况:
^[^( {16}| {12}| {8}| {4})]
但这样只匹配到空行或者以字符开头的行,并不是我想要的。
我对正则表达式完全是个新手,但我搜索了几个小时也没找到解决办法。我知道我可以直接列出所有不是4的倍数的数字来匹配,但我希望能有人帮我提供一个更简单的方法。
谢谢。
更新 1
使用正则表达式(@user2864740)
^(?:\s{4})*\s{1,3}\S
或者(@alpha bravo)
^(?!(\s{4})+\S)(.*)
可以匹配不是4的倍数的缩进,以及有4个(8、16等)空格的空行和紧接着的第一个非空行的第一个字符。
例如(在regex101.com上)
如何避免匹配上面例子中描述的这些情况?
3 个回答
1
你可以使用这个模式^(?!(\s{4})+\S)(.*)
来实现某些功能。这里有个示例
3
我可以提供一个Python脚本,它可以告诉你哪些行的缩进不正确:
with open('path/to/code/file') as infile:
for i,line in enumerate(infile,1):
total = len(line)
whitespace = total-len(line.lstrip(' '))
if whitespace%4:
print("Inconsistent indenting on line", i)
12
字符类只能包含一组特定的字符,所以像 [^..]
这样的写法不适合用来表示一般的否定。正则表达式 [^( {16}| {12}| {8}| {4})]
的意思是和 [^( {16}|284]
是一样的,它会匹配所有没有列出的 字符。
现在,要匹配 不是 4 的倍数的空格,其实就是在找 n mod 4 = {1, 2, 3}
(或者说 除了 n mod 4 = 0
)的空格。我们可以用下面这样的模式来实现:
(?:\s{4})*\s{1,3}\S
解释:
(?:\s{4})* - match any number of whole groups of 4 spaces and then ..
\s{1,3} - match any count of 1, 2, or 3 spaces such that ..
\S - they are not followed by a space
根据使用的情况,正则表达式可能需要在后面加一个点号通配符 .*
,或者在前面加一个行锚点 ^
。