2024-06-28 20:37:15 发布
网友
我对Regex不熟悉。数据的格式为“(实体A)-[:关系{}]>;(实体B)”,例如,(堪培拉)-[:大写{}]>;(澳大利亚)。如何提取两个实体及其关系?你知道吗
我尝试了以下代码:
path = "(Canberra)-[:capital_of {}]->(Australia)" pattern = r'\(.*\)\-\[\:.*\]\-\>\(.*\)' re.match(pattern,path).group()
但和整句话很吻合。任何帮助都将不胜感激。你知道吗
这看起来像是某种DSL,一种domains特定的l语言,因此您可以为它编写一个小型解析器。这里,我们使用a ^{} parser called ^{}。你知道吗
DSL
您需要一个小语法和一个NodeVisitor类:
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']
你就快到了。您需要通过将每个组封装在()中来定义要捕获的组。你知道吗
()
代码看起来像
import re path = "(Canberra)-[:capital_of {}]->(Australia)" pattern = r'\((.*)\)\-\[(:.*)\]\-\>\((.*)\)' print(re.match(pattern,path).groups())
输出将是
('Canberra', ':capital_of {}', 'Australia')
如果不需要使用regex,可以使用
s="(Canberra)-[:capital_of {}]->(Australia)" entityA = s[1:].split(')-')[0] entityB = s.split('->(')[-1][:-1]
根据')-'子字符串的出现情况拆分输入字符串,并取第一部分来获得第一个实体。你知道吗
')-'
split()是在'->('子字符串的基础上完成的,最后一次分割被选择来获得第二个实体。你知道吗
split()
'->('
所以
print(f'EntityA: {entityA}') print(f'EntityB: {entityB}')
会给
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)
这看起来像是某种} parser called ^{} 。你知道吗
DSL
,一种domains特定的l语言,因此您可以为它编写一个小型解析器。这里,我们使用a ^{您需要一个小语法和一个
NodeVisitor
类:这将产生
你就快到了。您需要通过将每个组封装在
()
中来定义要捕获的组。你知道吗代码看起来像
输出将是
如果不需要使用regex,可以使用
根据
')-'
子字符串的出现情况拆分输入字符串,并取第一部分来获得第一个实体。你知道吗split()
是在'->('
子字符串的基础上完成的,最后一次分割被选择来获得第二个实体。你知道吗所以
会给
非正则表达式解决方案通常更快。你知道吗
编辑:根据评论中的要求进行计时。你知道吗
相关问题 更多 >
编程相关推荐