我有一个字符串:
(A\2009_2009-01-04:0.2,(A\name2\human\2007_2007:0.3,A\chicken\ird16\2016_20016:0.4)A\name3\epi66321\2001_2001-04-04:0.5)A\name_with_space\2014_2014:0.1)A\name4\66036-8a\2004_2004-12-05;
在这棵树中, names 左侧用开括号“(”,一个右括号“)或逗号括起来,右边用冒号包围': ”。也就是说,子串“A \ 2009_2009-01-04”,“A \ name2 \ human \ 2007_2007”,“A \ name3 \ epi66321 \ 2001_2001-04-04”是名称。 (这实际上是newick格式的树)。
我想找到一个正则表达式模式,找到所有名称,尽可能少地限制命名空间。将名称视为变量,例如中的示例:
(A:0.1,B:0.2,(C:0.3,D:0.4)E:0.5)F;
其中A,B,C等可以是任何字符串。命名空间的唯一限制是名称不能包含圆括号或方括号,'&',','或':',因为这些是定义树格式的特殊字符,与逗号定义csv格式的方式相同。
奖励:有时,树中的内部节点没有标记:
(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);
在这种情况下,正确返回长度为零的字符串的正则表达式会很棒。
答案 0 :(得分:1)
您似乎想要提取以1 + (
,)
或,
开头的子字符串,然后包含除:
和{之外的1 +非空格字符尽可能多地{1}},但要停留在单词边界。
使用
;
请参阅regex demo。
模式详情
r'[(),]+([^;:]+)\b'
- 角色类中的一个或多个字符:[(),]+
,(
或)
,
- 第1组:尽可能多地使用([^;:]+)
和;
以外的一个或多个字符:
- 字边界\b
输出:
import re
rx = r'[(),]+([^;:]+)\b'
s = "(A:0.1,B:0.2,(C:0.3,D:0.4)E:0.5)F;((A\\2009_2009-01-04:0.2,(A\\name2\\human\\2007_2007:0.3,A\\chicken\\ird16\\2016_20016:0.4)A\\name3\\epi66321\\2001_2001-04-04:0.5)A\\name_with_space\\2014_2014:0.1)A\\name4\\66036-8a\\2004_2004-12-05;"
res = re.findall(rx, s)
for val in res:
print(val)
答案 1 :(得分:0)
你可以使用正则表达式
(\ w +)(?=:|;)
参见示例代码
import re
regex = r"(\w+)(?=:|;)"
test_str = "((B:0.2,(C:0.3,D:0.4)E:0.5)F:0.1)A;"
matches = re.finditer(regex, test_str)
for matchNum, match in enumerate(matches):
matchNum = matchNum + 1
print ("Match {matchNum} was found at {start}-{end}: {match}".format(matchNum = matchNum, start = match.start(), end = match.end(), match = match.group()))
输出
比赛1发现在2-3:B
比赛2在9-10:C发现 比赛3在15-16发现:D
比赛4在21-22发现:E
比赛5在27-28发现:F
第6场比赛在33-34发现:A
答案 2 :(得分:0)
答案 3 :(得分:0)
pattern = re.compile(r'[(),]A/[\S]*?:')
不是最优雅的,因为我利用了所有名字都以“A /”开头的事实。对于未来的用例,这不是真的,只是当前的用例。如果有人能找到更具普遍性的解决方案,请将这个问题保持开放。