Python 正则表达式全局用空格替换尾随零

标签 python regex string-formatting text-alignment

作为将 float 与表格数字数据的小数点分隔符对齐的解决方法,我试图找到一个正则表达式来用空格替换(全局后验)尾随零,规则如下:

  1. 小数点后无尾随零
  2. 如果小数点后第一位为零,则保留

还由于 Python 正则表达式引擎对需要固定宽度模式的后视的限制,我无法找到令人满意的解决方案。这是我尝试的一个工作示例(Python 3.x); 不要依赖解决方案中的竖线,它们出现在示例中只是为了清楚起见:

import re
# formatmany is just a way to speed up building of multiline string of tabular data
formatmany=lambda f:lambda *s:'\n'.join(f.format(*x) for x in s)

my_list = [[12345, 12.345, 12.345, 12.345],
           [12340, 12.34 , 12.34 , 12.34 ],
           [12345, 12.005, 12.005, 12.005],
           [12340, 12.04 , 12.04 , 12.04 ],
           [12300, 12.3  , 12.3  , 12.3  ],
           [12000, 12.0  , 12.0  , 12    ]]
my_format = formatmany('|{:8d}|{:8.2f}|{:8.3f}|{:8.4f}|')
my_string = my_format(*my_list) # this is the formatted multiline string with trailing zeros

print('\nOriginal string:\n')
print(my_string)
print('\nTry 1:\n')
print(re.sub(r'(?<!\.)0+(?=[^0-9\.]|$)',lambda m:' '*len(m.group()),my_string))
print('\nTry 2:\n')
print(re.sub(r'(\d)0+(?=[^\d]|$)',r'\1',my_string))

打印

Original string:

|   12345|   12.35|  12.345| 12.3450|
|   12340|   12.34|  12.340| 12.3400|
|   12345|   12.01|  12.005| 12.0050|
|   12340|   12.04|  12.040| 12.0400|
|   12300|   12.30|  12.300| 12.3000|
|   12000|   12.00|  12.000| 12.0000|

Try 1:

|   12345|   12.35|  12.345| 12.345 |
|   1234 |   12.34|  12.34 | 12.34  |
|   12345|   12.01|  12.005| 12.005 |
|   1234 |   12.04|  12.04 | 12.04  |
|   123  |   12.3 |  12.3  | 12.3   |
|   12   |   12.0 |  12.0  | 12.0   |

Try 2:

|   12345|   12.35|  12.345| 12.345|
|   1234|   12.34|  12.34| 12.34|
|   12345|   12.01|  12.005| 12.005|
|   1234|   12.04|  12.04| 12.04|
|   123|   12.3|  12.3| 12.3|
|   12|   12.0|  12.0| 12.0|

尝试 1 也替换整数中的尾随零,尝试 2 取自另一个用于替换单个 float 中的尾随零的解决方案。两者都不令人满意,因为所需的输出应该是:

|   12345|   12.35|  12.345| 12.345 |
|   12340|   12.34|  12.34 | 12.34  |
|   12345|   12.01|  12.005| 12.005 |
|   12340|   12.04|  12.04 | 12.04  |
|   12300|   12.3 |  12.3  | 12.3   |
|   12000|   12.0 |  12.0  | 12.0   |

为什么这不是重复的问题

  1. Python 正则表达式引擎与其他语言引擎略有不同,因此为其他语言提供的解决方案不会自动应用
  2. 要替换尾随零,而不是去除
  3. 这是关于多行字符串中多次出现的全局替换,而不仅仅是一次出现

最佳答案

stribizhev(之前但不令人满意)的回答给了我一个通用解决方案的想法:

re.sub(r'(?<=\.)(\d+?)(0+)(?=[^\d]|$)',lambda m:m.group(1)+' '*len(m.group(2))

关于Python 正则表达式全局用空格替换尾随零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32348435/

相关文章:

python - Python 的 str.format() 方法的默认 kwarg 值

python - 将 Window BAT(批处理)文件翻译成 Python 脚本

python - 如何加载文件选择器对话框

python - 将标量转换为 numpy 数组的有效方法

regex - 仅一组捕获数次

string-formatting - 本地化货币范围

python - 子进程 PIPE 标准输出到两个不同的进程

java - 在任意字符串中提取单个十进制数的最佳正则表达式

regex - 使用 regexp_split_to_array 将文本列拆分为 2

windows - 将文件大小转换为文本表示