在python re中分隔字符串中的第一个单词

在python re中分隔字符串中的第一个单词,python,regex,string,Python,Regex,String,我需要将字符串分为两组;第一个单词和第二个单词或一组单词。单词之间用下划线分隔,当我使用当前代码时,如果有多个下划线,则只将最后一个下划线分隔开。以下是我目前拥有的代码: for record in reader: s = record['trial'] patternsubgen = re.compile(r'(\w+)\(\w+\)\_(\w+)') source = "Footit" if patternsubgen.search(s): resultsubgen = patter

我需要将字符串分为两组;第一个单词和第二个单词或一组单词。单词之间用下划线分隔,当我使用当前代码时,如果有多个下划线,则只将最后一个下划线分隔开。以下是我目前拥有的代码:

for record in reader:
s = record['trial']
patternsubgen = re.compile(r'(\w+)\(\w+\)\_(\w+)')
source = "Footit"
if patternsubgen.search(s):
    resultsubgen = patternsubgen.search(s)
    genussubgen = resultsubgen.group(1)
    speciessubgen = resultsubgen.group(2)
    subgen = '%s %s' % (genussubgen, speciessubgen)
    #print(subgen)
else:
    pattern = re.compile(r'(\w+)\_(\w+)')
    if pattern.search(s):
        result = pattern.search(s)
        genus = result.group(1)
        species = result.group(2)
        new = '%s %s' % (genus, species)
        print(new)
以下是字符串的一些示例:

Aphis(Aphis)_asclepiadis, Cinara_011, Clydesmithia_canadensis_1a,
我需要的是:

Aphis asclepiadis,
Cinara 011,
Clydesmithia canadensis_1a,
我得到的是:

Aphis asclepiadis,
Cinara 011,
Clydesmithia_canadensis 1a
代码 选择1

替换

$1 $2
$1 $2
选择2

替换

$1 $2
$1 $2

结果 输入 输出 选项1

Aphis asclepiadis, Cinara 011, Clydesmithia canadensis_1a,
Aphis asclepiadis, Cinara 011, Clydesmithia canadensis_1a_test,
选项2

Aphis _asclepiadis, Cinara 011, Clydesmithia canadensis_1a,
Aphis test_asclepiadis, Cinara 011, Clydesmithia canadensis_1a_test,

解释 选择1
  • (\w+?(?=[(]))
    将以下内容捕获到捕获组1中
    • \w+?
      匹配一个或多个单词字符,但尽可能少
    • (?=[(])
      正向前瞻确保后面的内容与集合中的字符匹配
  • *?
    匹配任意字符任意次数,但尽可能少
  • 按字面意思匹配下划线字符
  • (\w+)
    将任何单词字符捕获一次或多次到捕获组2中
选择2
  • ([^\uw]+)
    将一个或多个单词字符捕获到捕获组1中,但
    除外
  • *?
    匹配任意字符任意次数,但尽可能少
  • [)\uu]
    按字面意思匹配
  • (\w+)
    将一个或多个单词字符捕获到捕获组2中

对于给定的字符串,可以使用

\b([^_\W]+)(?:\([^()]+\))?_(\w+)\b
看。
在Python中

import re

strings = 'Aphis(Aphis)_asclepiadis, Cinara_011, Clydesmithia_canadensis_1a,'

rx = re.compile(r'\b([^_\W]+)(?:\([^()]+\))?_(\w+)\b')

strings = rx.sub("\g<1> \g<2>", strings)
print(strings)
# Aphis asclepiadis, Cinara 011, Clydesmithia canadensis_1a,
重新导入
字符串='Aphis(Aphis)\u asclepiadis,Cinara\u 011,Clydesmithia\u canadensis\u 1a,'
rx=re.compile(r'\b([^\uw]+)(?:\([^()]+\)?\uw+\b')
strings=rx.sub(“\g\g”,strings)
打印(字符串)
#Aphis asclepiadis,Cinara 011,Clydesmithia Canadensis1a,

已经有了很好的正则表达式答案。不过,您可以单独使用正则表达式来实现目标。它接受一个指定最大拆分数的参数:

records = ["Aphis(Aphis)_asclepiadis", "Cinara_011", "Clydesmithia_canadensis_1a"]

for record in records:
    left, right = record.split('_', 1) # Split no more than once.
    left = left.split('(')[0]          # Remove anything after '('
    print(' '.join([left, right]))
# Aphis asclepiadis
# Cinara 011
# Clydesmithia canadensis_1a

顺便说一句,您不应该在循环中调用
re.compile
。这是一个昂贵的操作,而且模式不会在记录之间更改。

要求不够明确,因此会出现一些不明确的用例。但是结合您自己的代码和主题字符串,我会提供这样的正则表达式:

\(\w+\)_(\w+)|_(\w+)


在野外能找到这些细绳吗?关于加拿大一枝黄花(Clydesmithia_1a_2b)?类似的东西?关于Aphis(Aphis)呢test\u asclepiadis,Cinara\u 011,Clydesmithia\u canadensis\u 1a\u test,?@revo:不确定OP想要什么,真的。嗨,谢谢你的回答。我有两个问题:1.我如何重写代码,以避免编译两次;我需要在记录上执行其他操作,但我不知道如何在不编译的情况下执行这些操作。2.我尝试使用您提供的e代码,但我的终端显示“dict”对象没有“split”属性。我在csv.DictReader中-这可能是造成此问题的原因,还是存在其他问题?使用split可能会修复我遇到的其他一些问题,因此它可能非常有用。@birdoptera:只需将
re.compile
行移到for循环之前。
split
应该在字符串上调用,而不是在dict上调用。
\(\w+\)_(\w+)|_(\w+)