Python 使用regex重新订购版权
我需要把版权年放在字符串的开头。以下是我可能的输入:Python 使用regex重新订购版权,python,regex,Python,Regex,我需要把版权年放在字符串的开头。以下是我可能的输入: (c) 2012 10 DC Comics 2012 DC Comics 10 DC Comics. 2012 10 DC Comics , (c) 2012. 10 DC Comics, Copyright 2012 Warner Bros, 2011 Stanford and Sons, Ltd. Inc. (C) 2011. All Rights Reserved. ...etc... 从这些输入中,我需要始终以相同的格式输出- 20
(c) 2012 10 DC Comics
2012 DC Comics
10 DC Comics. 2012
10 DC Comics , (c) 2012.
10 DC Comics, Copyright 2012
Warner Bros, 2011
Stanford and Sons, Ltd. Inc. (C) 2011. All Rights Reserved.
...etc...
从这些输入中,我需要始终以相同的格式输出-
2012. 10 DC Comics.
2011. Warner Bros.
2011. Stanford and Sons, Ltd. Inc. All Rights Reserved
etc...
如何结合使用字符串格式和正则表达式来实现这一点
这需要清理,但这是我目前正在做的:
### copyright
copyright = value_from_key(sd_wb, 'COPYRIGHT', n).strip()
m = re.search('[0-2][0-9][0-9][0-9]', copyright)
try:
year = m.group(0)
except AttributeError:
copyright=''
else:
copyright = year + ". " + copyright.replace(year,'')
copyright = copyright.rstrip('.').strip() + '.'
if copyright:
copyright=copyright.replace('\xc2\xa9 ','').replace('&', '&').replace('(c)','').replace('(C)','').replace('Copyright', '')
if not copyright.endswith('.'):
copyright = copyright + '.'
copyright = copyright.replace(' ', ' ')
一个不使用正则表达式的答案怎么样
tests = (
'(c) 2012 DC Comics',
'DC Comics. 2012',
'DC Comics, (c) 2012.',
'DC Comics, Copyright 2012',
'(c) 2012 10 DC Comics',
'10 DC Comics. 2012',
'10 DC Comics , (c) 2012.',
'10 DC Comics, Copyright 2012',
'Warner Bros, 2011',
'Stanford and Sons, Ltd. Inc. (C) 2011. All Rights Reserved.',
)
def reorder_copyright(text):
year = None
first = []
second = []
words = text.split()
if words[0].lower() in ('(c)','copyright'):
year = words[1]
company = ' '.join(words[2:])
for i, word in enumerate(words):
if word.lower() in ('(c)','copyright'):
year = words[i+1]
company = ' '.join(words[:i] + words[i+2:])
break
else:
year = words[-1]
company = ' '.join(words[:-1])
year = year.strip(' ,.')
company = company.strip(' ,.')
return "%s. %s." % (year, company)
if __name__ == '__main__':
for line in tests:
print(reorder_copyright(line))
搜寻
^(c\)\s+(?P\d{4})\s+(?P\d{2})。*$P\d{2}.*(?P\d{4})\。?
替换
\g<year>. \g<digits> DC Comics.
\g\g DC漫画。
这适用于任何四位数年份(不仅仅是2012年)和任何两位数数字(不仅仅是10年)。不知道你是否需要。这太难看了,无法解释:)
编辑:在我发布这个答案后,OP改变了输入和输出,所以它不会工作。往前走,这里什么也看不见。这很混乱,我不确定你会得到一个完美的解决方案,但你可以通过做三件事来实现大部分目标:
|
排序不同regexp的列表,这些regexp将匹配第一个可以匹配的regexp(从左到右),例如,您希望在“2012”之前匹配“(c)2012”之前
,年份
,以及之后
,其中之前
或之后
可能不存在,但它们一起可以为您提供所需的结果,但年份除外
换句话说,在之前、年份和之后使用b
、y
和a
:
(c) 2012 10 DC Comics
yyyy aaaaaaaaaaaa
2012 DC Comics
yyyy aaaaaaaaa
10 DC Comics , (c) 2012.
bbbbbbbbbbbb yyyy
Stanford and Sons, Ltd. Inc. (C) 2011. All Rights Reserved.
bbbbbbbbbbbbbbbbbbbbbbbbbbbb yyyy aaaaaaaaaaaaaaaaaaaa
(请注意,我们没有命名“(c)”等,因为您不希望这样)
因此,考虑到上述情况,第一次尝试regexp可能是:
(?i)(?:(?P<before>.*)\s*Copyright\s*(?P<year>\d{4})(?P<after>.*)|
(?P<before>.*)\s*\(c\)\s*(?P<year>\d{4})(?P<after>.*)|
(?P<before>.*)\s*(?P<year>\d{4})(?P<after>.*))
或者,使用.sub()
,类似于:
d = match.groupdict()
d['year'] + ' ' + d.get('before', '') + ' ' + d.get('after', '')
re.sub(..., r'\g<year> \g<before> \g<after>', ...)
re.sub(…,r'\g\g\g',…)
最后,您可能会发现需要另一个过程来删除奇怪的标点符号(删除紧跟句点的任何逗号,用一个空格替换多个空格等)。此程序:
from __future__ import print_function
import re
tests = (
'(c) 2012 DC Comics',
'DC Comics. 2012',
'DC Comics, (c) 2012.',
'DC Comics, Copyright 2012',
'(c) 2012 10 DC Comics',
'10 DC Comics. 2012',
'10 DC Comics , (c) 2012.',
'10 DC Comics, Copyright 2012',
'Warner Bros, 2011',
'Stanford and Sons, Ltd. Inc. (C) 2011. All Rights Reserved.',
)
for input in tests:
print("<", input)
output = re.sub(r'''
(?P<lead> (?: \S .*? \S )?? )
[\s.,]*
(?: (?: \( c \) | copyright ) \s+ )?
(?P<year> (?:19|20)\d\d )
[\s.,]?
''', r"\g<year>. \g<lead>", input, 1, re.I + re.X)
print(">", output, "\n")
from\uuuuu future\uuuuu导入打印功能
进口稀土
测试=(
"(c)2012 DC漫画",,
“DC漫画2012”,
“DC漫画(c)2012”,
“DC漫画,版权所有2012”,
"(c)2012年10DC漫画",,
“10 DC漫画2012”,
“10 DC漫画,(c)2012”,
“10 DC漫画,版权所有2012”,
“华纳兄弟,2011年”,
“斯坦福父子有限公司(C)2011。保留所有权利。”,
)
对于测试中的输入:
打印(“,输出“\n”)
在Python 2.7或3.2下运行时,生成以下输出:
< (c) 2012 DC Comics
> 2012. DC Comics
< DC Comics. 2012
> 2012. DC Comics
< DC Comics, (c) 2012.
> 2012. DC Comics
< DC Comics, Copyright 2012
> 2012. DC Comics
< (c) 2012 10 DC Comics
> 2012. 10 DC Comics
< 10 DC Comics. 2012
> 2012. 10 DC Comics
< 10 DC Comics , (c) 2012.
> 2012. 10 DC Comics
< 10 DC Comics, Copyright 2012
> 2012. 10 DC Comics
< Warner Bros, 2011
> 2011. Warner Bros
< Stanford and Sons, Ltd. Inc. (C) 2011. All Rights Reserved.
> 2011. Stanford and Sons, Ltd. Inc All Rights Reserved.
<(c)2012 DC漫画
> 2012. DC漫画
2012. DC漫画
2012. DC漫画
2012. DC漫画
<(c)2012年10部DC漫画
> 2012. 10 DC漫画
<10 DC漫画。2012
> 2012. 10 DC漫画
<10 DC漫画,(c)2012年。
> 2012. 10 DC漫画
<10 DC漫画,版权所有2012
> 2012. 10 DC漫画
<华纳兄弟,2011年
> 2011. 华纳兄弟
<斯坦福父子有限公司(C)2011年。版权所有。
> 2011. 斯坦福父子有限公司保留所有权利。
这似乎就是您要找的。好吧,在我发布答案后,您更改了输入。所以它不会对你所有的(新的)输入都起作用。谢谢你的回答。抱歉,我更新了一点,因为我的初始输入太窄。我对正则表达式很糟糕(谁不是?),但是,如果你只得到数字,你应该以年份结束,如果你只得到空格和字母,你应该得到名称。都是DC漫画和2012吗?我开始为它编写一些代码,但如果您在示例输入/输出中包含边界案例,这将非常有用。不,它可以是任何公司。这里有一些关于版权如何呈现的语法示例(很明显,公司名称中可以有数字)。你能把它缩小到所有可能的公司的列表吗?因为很难解释空格、标点符号和版权措辞,这将使它变得更加容易。@DanRedux嗯,我不是
< (c) 2012 DC Comics
> 2012. DC Comics
< DC Comics. 2012
> 2012. DC Comics
< DC Comics, (c) 2012.
> 2012. DC Comics
< DC Comics, Copyright 2012
> 2012. DC Comics
< (c) 2012 10 DC Comics
> 2012. 10 DC Comics
< 10 DC Comics. 2012
> 2012. 10 DC Comics
< 10 DC Comics , (c) 2012.
> 2012. 10 DC Comics
< 10 DC Comics, Copyright 2012
> 2012. 10 DC Comics
< Warner Bros, 2011
> 2011. Warner Bros
< Stanford and Sons, Ltd. Inc. (C) 2011. All Rights Reserved.
> 2011. Stanford and Sons, Ltd. Inc All Rights Reserved.