Python如何强制一个字符串匹配另一个字符串的格式
我有一些为我工作的评估员办公室编写的Python脚本。其中大多数要求输入地块ID号(然后通过odbc获取特定数据)。他们输入包裹ID的方式不太一致 这就是我的问题,他们通过以下三种方式之一输入地块ID: 1:'1005191000060' 2:'001005191000060' 3:'0010-05-19-100-006-0' 第三种方法是正确的方法,因此我需要确保输入是固定的,以始终匹配该格式。当然,他们宁愿输入前两种方式之一的ID。地块编号必须始终为15位(20位带破折号) 我目前有一个关于如何修复地块ID的工作方法,但它非常难看。我想知道是否有人知道一个更好的方法(或者更“Pythonic”的方法)。我有一个函数,通常被导入到所有这些脚本中。以下是我所拥有的:Python如何强制一个字符串匹配另一个字符串的格式,python,regex,string,python-2.7,formatting,Python,Regex,String,Python 2.7,Formatting,我有一些为我工作的评估员办公室编写的Python脚本。其中大多数要求输入地块ID号(然后通过odbc获取特定数据)。他们输入包裹ID的方式不太一致 这就是我的问题,他们通过以下三种方式之一输入地块ID: 1:'1005191000060' 2:'001005191000060' 3:'0010-05-19-100-006-0' 第三种方法是正确的方法,因此我需要确保输入是固定的,以始终匹配该格式。当然,他们宁愿输入前两种方式之一的ID。地块编号必须始终为15位(20位带破折号) 我目前有一个关于
import re
def FormatPID(in_pid):
pid_format = re.compile('\d{4}-\d{2}-\d{2}-\d{3}-\d{3}-\d{1}')
pid = in_pid.zfill(15)
if not pid_format.match(pid):
fixed_pid = '-'.join([pid[:4],pid[4:6],pid[6:8],pid[8:11],pid[11:-1],pid[-1]])
return fixed_pid
else:
return pid
if __name__ == '__main__':
pid = '1005191000060'
## pid = '001005191000060'
## pid = '0010-05-19-100-006-0'
# test
t = FormatPID(pid)
print t
这确实工作得很好,但我已经被这段丑陋的代码困扰了一段时间,我想一定有比切片更好的方法。我希望有一种方法可以“强制”将其转换为字符串以匹配“pid_格式”变量。有什么想法吗?我在正则表达式模块中找不到任何可以执行此操作的方法,您可以使用
itertools.islice
代替手动切片:
import re
from itertools import islice
groups = (4, 2, 2, 3, 3, 1)
def FormatPID(in_pid):
pid_format = re.compile('\d{4}-\d{2}-\d{2}-\d{3}-\d{3}-\d{1}')
in_pid = in_pid.zfill(15)
if not pid_format.match(in_pid):
it = iter(in_pid)
return '-'.join(''.join(islice(it, i)) for i in groups)
return in_pid
print FormatPID('1005191000060')
print FormatPID('001005191000060')
print FormatPID('0010-05-19-100-006-0')
输出:
0010-05-19-100-006-0
0010-05-19-100-006-0
0010-05-19-100-006-0
我不会费心使用正则表达式。你只想得到所有的数字,忽略连字符,左边填充0,然后在正确的位置插入连字符,对吗?因此:
def format_pid(pid):
p = pid.replace('-', '')
if not p.isdigit():
raise ValueError('Invalid format: {}'.format(pid))
p = p.zfill(15)
# You can use your `join` call instead of the following if you prefer.
# Or Ashwini's islice call.
return '{}-{}-{}-{}-{}-{}'.format(p[:4], p[4:6], p[6:8], p[8:11], p[11:14], p[14:])
我认为他不想做任何填充,他希望他们输入准确的数字,然后将破折号插入适当的位置。@EricAmorde:如果他不想做任何填充,示例1将如何工作?谢谢abarnert。不过,我想我会坚持埃里克的回答。我想摆脱“丑陋的切片”。这和我原来的帖子没什么不同。尽管如此,我还是喜欢使用isdigit()而不是我的正则表达式。我对“\d”的使用不会做同样的事情吗?文档说明:\d未指定UNICODE标志时,匹配任何十进制数字;这相当于集合[0-9]。使用UNICODE,它将匹配UNICODE字符属性数据库中分类为十进制数字的任何内容。@cmackey:嗯,
isdigit()
将执行与显式编写的正则表达式相同的操作,以表示与isdigit()
相同的操作。这将更简单、更快,更难出错。但请注意,您的代码假设要么所有连字符都在正确的位置,要么只有数字;我的代码是检查你是否只有数字或连字符,忽略连字符,然后使用数字。很好…我试图找到与此类似的东西。我只是讨厌看我正在做的丑陋的切片手术。非常感谢你!