【问题标题】:String Formatting/Template/Regular Expressions字符串格式/模板/正则表达式
【发布时间】:2015-07-03 19:18:47
【问题描述】:

我有一个字符串格式,假设 A = 字母数字和 N = 整数,所以模板是“AAAAAA-NNNN”,现在用户有时会省略破折号,有时“NNNN”只有三位数,在这种情况下我需要它填充一个 0。“NNNN”的第一个数字必须是 0,因此如果它是一个数字,则它是“AAAAAA”的最后一个数字,而不是“NNNN”的第一个数字。所以本质上,如果我有以下输入,我想要以下结果:

示例输入:

"SAMPLE0001"
"SAMPL1-0002"
"SAMPL3003"
"SAMPLE-004"

期望的输出:

"SAMPLE-0001"
"SAMPL1-0002"
"SAMPL3-0003"
"SAMPLE-0004"

我知道如何使用正则表达式来检查这一点,但基本上我想做相反的事情。我想知道是否有一种简单的方法可以做到这一点,而不是对所有这些变化进行嵌套条件检查。我正在使用 python 和 pandas,但两者都足够了。

正则表达式模式是:

"[a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9][a-zA-Z0-9]-\d\d\d\d"

或缩写形式:

"[a-zA-Z0-9]{6}-[\d]{4}"

【问题讨论】:

  • 仅供参考...您可以像这样简化底部的正则表达式[a-zA-Z]{6}-[\d]{4}
  • 上述正则表达式如何将SAMPLE003转换为SAMPLE-0003
  • 不会,这就是我要解决的问题
  • @aensm 它不会匹配第二种情况。
  • 感谢 aensm 的缩写语法

标签: python regex string pandas formatting


【解决方案1】:

这可以通过两个re.sub 函数来实现。

>>> import re
>>> s = '''SAMPLE0001
SAMPL1-0002
SAMPL3003
SAMPLE-004'''
>>> print(re.sub(r'(?m)(?<=-)(?=\d{3}$)', '0', re.sub(r'(?m)(?<=^[A-Z\d]{6})(?!-)', '-', s)))
SAMPLE-0001
SAMPL1-0002
SAMPL3-0003
SAMPLE-0004

解释:

  • re.sub(r'(?m)(?&lt;=^[A-Z\d]{6})(?!-)', '-', s) 将首先被处理。只有当后面的字符不是连字符时,它才会在从头开始的第 6 个字符之后放置一个连字符。

  • re.sub(r'(?m)(?&lt;=-)(?=\d{3}$)', '0', re.sub(r'(?m)(?&lt;=^[A-Z\d]{6})(?!-)', '-', s)) 通过将上述命令的输出作为输入,这将在连字符后添加一个数字 0,并且后面的字符必须正好是 3。

【讨论】:

  • 你是什么正则表达式之王?所以让我再等一分钟来接受答案!
  • 现在我只需要弄清楚这一切意味着什么 :) 但它有效!
【解决方案2】:

另一种解决方案,它使用str.join

import re
inputs = ['SAMPLE0001', 'SAMPL1-0002', 'SAMPL3003','SAMPLE-004']
outputs = []
for input_ in inputs:
    m = re.match(r'(\w{6})-?\d?(\d{3})', input_)
    outputs.append('-0'.join(m.groups()))
print(outputs)
# ['SAMPLE-0001', 'SAMPL1-0002', 'SAMPL3-0003', 'SAMPLE-0004']

我们将正则表达式 (\w{6})-?\d?(\d{3}) 与输入字符串进行匹配,并将捕获的组与字符串 '-0' 连接起来。这是非常简单和快速的。

如果您需要更深入地解释正则表达式本身,请告诉我。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-28
    • 2023-04-08
    • 2018-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多