使用正则表达式 python 由 `|` 分隔的标签中的错误
Posted
技术标签:
【中文标题】使用正则表达式 python 由 `|` 分隔的标签中的错误【英文标题】:Error in tag separated by `|` using Regex python 【发布时间】:2020-06-08 21:17:42 【问题描述】:我想在每个标签之前添加|
。
请检查我使用的以下代码。
tags = ['XYZ', 'CREF', 'BREF', 'RREF', 'REF']
string_data = 'XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY'
for each_tag in tags:
result = string_data.replace(each_tag, "|" + each_tag)
print(result)
我怎样才能使用正则表达式?
输入字符串:
XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY
实际结果(错误):
XYZ:MUMBAI UNIVERSITYC|REF:PUNE UNIVERSITYB|REF:DADAR UNIVERSITYR|REF:KOLHAPUR UNIVERCITY LLC|REF:SOLAPUR UNIVERSITY
预期结果:
|XYZ:MUMBAI UNIVERSITY|CREF:PUNE UNIVERSITY|BREF:DADAR UNIVERSITY|RREF:KOLHAPUR UNIVERCITY LLC|REF:SOLAPUR UNIVERSITY
有什么方法可以使用正则表达式吗?
【问题讨论】:
很遗憾,我们无法知道“LLCREF:”应该是“LLC/REF:”还是“LL/CREF:”。 不需要正则表达式。使用这样的东西:"|" + "|".join(['XYZ', 'CREF', 'BREF', 'RREF'])
你的错误结果和预期的输出看起来一样,对吧?
@GaganTK 否,请检查上述错误结果和预期结果。
@AkshayGodase 好的,知道了。您能否将您尝试过的代码添加到问题中?
【参考方案1】:
重新导入
string = "XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERSITY LLCREF:SOLAPUR UNIVERSITY"
regx = "(XYZ|[C|B|R]REF|REF):[a-zA-Z\s]+?(LLC)?(?=(XYZ|[C|B|R]REF )|REF|$)"
matches = re.finditer(regx, string)
标签 = []
匹配中的匹配: tag.append(match.group())
结果=“|” + "|".join(标签) 打印(结果)
【讨论】:
欢迎来到 ***,并祝贺您的第一篇文章。如果您将代码格式化为代码,并添加一些文本来描述您的答案为何/如何起作用,您将获得更积极的回应(即支持和提高声誉)。【参考方案2】:您可以匹配可选的B
或R
,或者在前面没有L
的情况下匹配C
,使用否定后向查找。
(?:[BR]?|(?<!L)C)REF|^(?!\|)
说明
(?:
非捕获组
[BR]?
匹配可选的 B
或 R
|
或者
(?<!L)C
匹配 C
并断言左边的不是 L
)
关闭群
REF
字面匹配
|
或者
^(?!\|)
断言字符串的开头不是直接跟在 |
之后,以防止在已经存在的情况下以双 ||
开头
Regex demo | Python demo
在替换中使用以管道开头的匹配
|\g<0>
例如
import re
regex = r"(?:[BR]?|(?<!L)C)REF|^(?!\|)"
test_str = "XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY"
subst = "|\\g<0>"
result = re.sub(regex, subst, test_str)
print (result)
输出
|XYZ:MUMBAI UNIVERSITY|CREF:PUNE UNIVERSITY|BREF:DADAR UNIVERSITY|RREF:KOLHAPUR UNIVERCITY LLC|REF:SOLAPUR UNIVERSITY
【讨论】:
@The_fourth_bird 它工作成功。如果我在另一个字符串上测试过它,比如"XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLBREF:SOLAPUR UNIVERSITY"
,那么它就不起作用了。这适用于任何情况意味着如果在 REF
之前如果我在 A-Z 中有任何后者,那么我会工作。
@The_fourth_bird 请检查上面的注释突出显示的字符串。如果您有任何问题,请告诉我。
您可以在后视中使用字符类 A-Z。 regex101.com/r/KtfLAR/1 但它与 LLLREF
不匹配。这种情况下的预期是什么?你能更新 regex101 链接什么应该和什么不应该匹配?【参考方案3】:
由于您最重要的问题是正确拆分字符串,因此我仅尝试解决此问题。您可以在之后附加和前置 |
。
这种模式似乎奏效了:
(XYZ|CREF|BREF|RREF|REF):[a-zA-Z\\s]+?(LLC)?(?=(XYZ|CREF|BREF|RREF|REF)|$)
解释:
(XYZ|CREF|BREF|RREF|REF):
: 这很明显。您正在寻找标签的开头。顺序很重要。也就是把最短的子串REF
放在最后。
[a-zA-Z\\s]+?
:匹配标记后出现的任何字符和空格,不情愿地。不情愿,因为如果引擎到达CREF
的开头,我们希望它停在那里而不是“贪婪地”获取更多字符。由于使用了“不情愿”,第 (4) 点中的标签顺序很重要。
(LLC)?
: 这是一种以标签开头的字符序列结尾的所有已知单词的例外列表。 (为此,我想不出任何其他方式。)必须知道异常列表,并且可以单独配置并附加到模式运行时。如果事先知道输入数据结构并且此类异常是有限且已知的,则这不是瓶颈。否则,是的。
(?=(XYZ|CREF|BREF|RREF|REF)|$)
: 确保引擎在发现其中一个标签出现时停止。 $
允许在输入结束时停止,如果没有更多标签。
这将为您提供的输入字符串提供以下输出:
XYZ:MUMBAI UNIVERSITY
CREF:PUNE UNIVERSITY
BREF:DADAR UNIVERSITY
RREF:KOLHAPUR UNIVERCITY LLC
REF:SOLAPUR UNIVERSITY
编辑
添加我测试过的 Python 3.8.1 代码:
import re
s = "XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY"
p = "(XYZ|CREF|BREF|RREF|REF):[a-zA-Z\\s]+?(LLC)?(?=(XYZ|CREF|BREF|RREF|REF)|$)"
matches = re.finditer( p,s )
tag_list = [ m.group() for m in matches ]
s2 = "|" + "|".join( tag_list )
print( s2 )
【讨论】:
@Sree_Kumar 尝试了上面的代码,但没有得到结果。 @AkshayGodase 我已经发布了我用来测试的代码。你能查一下吗? @Sreee_Kumar 我已经测试了你的代码,它可以正常工作。但我期待预期的结果。请检查以下|XYZ:MUMBAI UNIVERSITY|CREF:PUNE UNIVERSITY|BREF:DADAR UNIVERSITY|RREF:KOLHAPUR UNIVERCITY LLC|REF:SOLAPUR UNIVERSITY
我不想在结果上方分离我需要的所有组
好的。在这之后简单地加入零件还不够吗?或者你想要一个正则表达式级别替换的解决方案?【参考方案4】:
您的问题是 'CREF'
、'BREF'
、'RREF'
和 'REF'
之间的重复 - 因为 'REF'
在所有其他三个中,如果您将代码修复为此,您最终会得到重复的替换:
tags = ['XYZ', 'CREF', 'BREF', 'RREF', 'REF']
string_data = 'XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY'
for each_tag in tags:
string_data= string_data.replace(each_tag, "|" + each_tag)
print(string_data)
您需要确保仅在 'C'
、'B'
或 'R'
之前没有替换 'REF'
。
请注意,对于 XYZ:CARE BEARREF
等某些情况,这仍然会导致问题。 IE。你可能会期待|XYZ:CARE BEAR|REF
,但你会得到|XYZ:CARE BEA|RREF
。如果您想避免这种情况,您需要更准确地了解实际规则。
如果您知道不会发生此类问题,这可行:
import re
string_data = 'XYZ:MUMBAI UNIVERSITYCREF:PUNE UNIVERSITYBREF:DADAR UNIVERSITYRREF:KOLHAPUR UNIVERCITY LLCREF:SOLAPUR UNIVERSITY'
result = re.sub("(XYZ|CREF|BREF|RREF|REF)", r"|\1", string_data )
print(result)
这避免了特定的检查,因为正则表达式会考虑排序,并且在文本已作为先前值的一部分匹配后不会匹配 REF。
【讨论】:
我尝试了您的代码,但我的预期结果与您的结果不匹配。以上是关于使用正则表达式 python 由 `|` 分隔的标签中的错误的主要内容,如果未能解决你的问题,请参考以下文章