Python 如何使用正则表达式提取多个字符串
我对Regex不熟悉。数据的格式为“(实体A)-[:RELATION{}]>(实体B)”,例如,(堪培拉)-[:capital_of{}]>(澳大利亚)。如何提取两个实体及其关系 我尝试了以下代码:Python 如何使用正则表达式提取多个字符串,python,regex,Python,Regex,我对Regex不熟悉。数据的格式为“(实体A)-[:RELATION{}]>(实体B)”,例如,(堪培拉)-[:capital_of{}]>(澳大利亚)。如何提取两个实体及其关系 我尝试了以下代码: path=“(堪培拉)-[:澳大利亚首都{}]>” 模式=r'\(.\)\-\[\:.\]\-\>\(.\)' re.match(模式、路径).group() 但它和整个句子是一致的。任何帮助都将不胜感激。您就快到了。您需要定义要捕获的每个组,方法是将其包含在()中 代码如下所示 import r
path=“(堪培拉)-[:澳大利亚首都{}]>”
模式=r'\(.\)\-\[\:.\]\-\>\(.\)'
re.match(模式、路径).group()
但它和整个句子是一致的。任何帮助都将不胜感激。您就快到了。您需要定义要捕获的每个组,方法是将其包含在
()
中
代码如下所示
import re
path = "(Canberra)-[:capital_of {}]->(Australia)"
pattern = r'\((.*)\)\-\[(:.*)\]\-\>\((.*)\)'
print(re.match(pattern,path).groups())
输出将是
('Canberra', ':capital_of {}', 'Australia')
如果不需要使用正则表达式,可以使用
s="(Canberra)-[:capital_of {}]->(Australia)"
entityA = s[1:].split(')-')[0]
entityB = s.split('->(')[-1][:-1]
输入字符串根据出现的)-“
子字符串进行拆分,并取第一部分以获得第一个实体
split()
所以
会给
EntityA: Canberra
EntityB: Australia
非正则表达式解决方案通常更快
编辑:按注释中的要求进行计时
s="(Canberra)-[:capital_of {}]->(Australia)"
def regex_soln(s):
pattern = r'\((.*)\)\-\[(:.*)\]\-\>\((.*)\)'
rv = re.match(pattern,s).groups()
return rv[0], rv[-1]
def non_regex_soln(s):
return s[1:].split(')-')[0], s.split('->(')[-1][:-1]
%timeit regex_soln(s)
1.47 µs ± 60.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
%timeit non_regex_soln(s)
619 ns ± 30.9 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
这看起来像是一些DSL
,一种domainsspecificl语言,因此您可以为它编写一个小的解析器
您需要一个小语法和一个NodeVisitor
类:
from parsimonious.grammar import Grammar
from parsimonious.nodes import NodeVisitor
path = "(Canberra)-[:capital_of {}]->(Australia)"
class PathVisitor(NodeVisitor):
grammar = Grammar(
r"""
path = (pair junk?)+
pair = lpar notpar rpar
lpar = ~"[(\[]+"
rpar = ~"[)\]]+"
notpar = ~"[^][()]+"
junk = ~"[-:>]+"
"""
)
def generic_visit(self, node, visited_children):
return visited_children or node
def visit_pair(self, node, visited_children):
_, value, _ = visited_children
return value.text
def visit_path(self, node, visited_children):
return [child[0] for child in visited_children]
pv = PathVisitor()
output = pv.parse(path)
print(output)
这将产生
['Canberra', ':capital_of {}', 'Australia']
每个括号是否呈现一个组?是的,并且你想隔离每个组,例如<代码>(*)>代码>是一个组,<代码>(:*)/代码>是另一个酷!很高兴帮助@ SrRuiLi:如果答案帮助你,请考虑将它标记为通过点击答案旁边的刻度来接受。我还建议您更精确地查看,您可以说不是一个)
([^]+
)而不是点星汤;-)我的意思是113个步骤()和18个步骤()你能解释一下你是如何想出非正则表达式的解决方案通常更快。
?您是否对正则表达式和非正则表达式解决方案计时。如果能看到一个比较就太好了:)@deveshkumarsing是的,我计时了。但请注意,我对正则表达式知之甚少。:-)如果你能的话,你能加上计时数字吗?它们确实很快,但速度只有2.5倍,而且生成的列表的额外空间和拆分的复杂性可能会随着表达式变得更复杂而增加,无论如何+1对于计时数字来说,对于初学者,我更喜欢一个三周内就能理解的答案,而不是刺激速度。。。
['Canberra', ':capital_of {}', 'Australia']