Python中如何按照前缀最短空格缩进处理多行文本
假设有这样一个文本
1234
123456
12345678
1234
我想要按照前缀最短空格缩进,即上述文本最短空格为 4 ,就把整个文本都向左缩进 4 个空格
目前想到的方法是先遍历一遍,找出最短空格,再遍历一遍,逐行缩进,请教一下还有更好的方法吗?
Python中如何按照前缀最短空格缩进处理多行文本
7 回复
基本上就是这个思路,没法再更简单了。
import re
def indent_by_shortest_prefix(text):
"""
按照前缀最短空格缩进处理多行文本
原理:
1. 找出所有非空行的最小公共前缀空格数
2. 每行都减去这个最小空格数
3. 保留空行的原始状态
"""
if not text:
return text
lines = text.splitlines()
# 找出所有非空行的前导空格数
leading_spaces = []
for line in lines:
if line.strip(): # 非空行
match = re.match(r'^(\s*)', line)
if match:
leading_spaces.append(len(match.group(1)))
if not leading_spaces: # 全是空行
return text
# 计算最小缩进
min_indent = min(leading_spaces)
# 重新构建文本
result_lines = []
for line in lines:
if line.strip() and len(line) >= min_indent:
# 非空行且长度足够,去除最小缩进
result_lines.append(line[min_indent:])
else:
# 空行或长度不足,保持原样
result_lines.append(line)
return '\n'.join(result_lines)
# 测试示例
if __name__ == "__main__":
# 示例1:常规缩进
text1 = """ def hello():
print("Hello")
if True:
print("World")
def goodbye():
print("Goodbye")"""
print("原始文本1:")
print(text1)
print("\n处理结果1:")
print(indent_by_shortest_prefix(text1))
# 示例2:混合缩进
text2 = """ line1
line2
line3
line4"""
print("\n\n原始文本2:")
print(text2)
print("\n处理结果2:")
print(indent_by_shortest_prefix(text2))
# 示例3:有空行
text3 = """ first line
second line
third line"""
print("\n\n原始文本3:")
print(text3)
print("\n处理结果3:")
print(indent_by_shortest_prefix(text3))
这个函数的工作原理:
- 首先找出所有非空行的前导空格数量
- 计算这些空格数的最小值
- 对每行文本,如果是非空行就减去这个最小空格数
- 空行保持原样不处理
关键点:
- 使用正则表达式
r'^(\s*)'匹配每行开头的空格 line.strip()判断是否为空行(包含空白字符的行)- 空行不参与最小缩进的计算,保持原样输出
测试用例展示了不同情况:
- 统一缩进的代码块
- 混合缩进的文本
- 包含空行的文本
处理后的文本会保持原有的相对缩进关系,只是整体向左移动,使最小缩进变为0。
一句话总结:找出最小公共缩进并整体左移。
会 vi,但我需要使用程序进行处理,另外我记得 vi 貌似也没这个功能
- 首先确认 最短几个空格,比如 3 个
2. :%s/^_ *//g (祛除所以开头空格,下划线 表示一个空格的意思,注意)
3. :%/^/___/g (所有开开头加 3 个空格)
三秒解决问题
嗯,你是对的


