如何提取两个标记之间的子串?

mie*_*nik 288 python string substring

假设我有一个字符串'gfgfdAAA1234ZZZuijjk',我想只提取'1234'部分.

我只知道在我感兴趣的部分之前AAA和之后ZZZ的几个字符是什么1234.

使用sed它可以用字符串做这样的事情:

echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"
Run Code Online (Sandbox Code Playgroud)

这将给我1234带来的结果.

如何在Python中做同样的事情?

eum*_*iro 511

使用正则表达式 - 文档以供进一步参考

import re

text = 'gfgfdAAA1234ZZZuijjk'

m = re.search('AAA(.+?)ZZZ', text)
if m:
    found = m.group(1)

# found: 1234
Run Code Online (Sandbox Code Playgroud)

要么:

import re

text = 'gfgfdAAA1234ZZZuijjk'

try:
    found = re.search('AAA(.+?)ZZZ', text).group(1)
except AttributeError:
    # AAA, ZZZ not found in the original string
    found = '' # apply your error handling

# found: 1234
Run Code Online (Sandbox Code Playgroud)

  • @Alexander,no,group(0)将返回完全匹配的字符串:AAA1234ZZZ,group(1)将仅返回与第一组匹配的字符:1234 (19认同)
  • 第二种解决方案更好,如果模式大部分时间匹配,因为它[更容易要求宽恕而非许可.](http://docs.python.org/3/glossary.html#term-eafp). (16认同)
  • 索引是否从0开始?那么你需要使用group(0)而不是group(1)? (6认同)
  • 在这个表达式中?将+修改为非贪婪,即 它会从1向上匹配任意多次,但次数尽可能少,只会根据需要扩展。如果没有?,第一个群组会将gfgfAAA2ZZZkeAAA43ZZZonife匹配为2ZZZkeAAA43,但带有?它只会匹配2,然后搜索多个(或将其删除并再次搜索)将匹配43。 (4认同)
  • @Bengt:这是为什么?第一个解决方案对我来说看起来很简单,它的代码行更少。 (2认同)

Len*_*bro 105

>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> start = s.find('AAA') + 3
>>> end = s.find('ZZZ', start)
>>> s[start:end]
'1234'
Run Code Online (Sandbox Code Playgroud)

然后,如果需要,也可以将regexps与re模块一起使用,但在您的情况下这不是必需的.

  • 问题似乎暗示输入文本将始终包含"AAA"和"ZZZ".如果不是这种情况,你的答案就会失败(我的意思是它会返回一些完全错误而不是空字符串或抛出异常;想想"你好那里"作为输入字符串). (9认同)
  • 投票,但为了可维护性,我会使用“x = 'AAA'; s.find(x) + len(x)”而不是“s.find('AAA') + 3”。 (2认同)

tzo*_*zot 52

正则表达式

import re

re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)
Run Code Online (Sandbox Code Playgroud)

AttributeError如果没有"AAA"和"ZZZ",则上述原样将失败your_text

字符串方法

your_text.partition("AAA")[2].partition("ZZZ")[0]
Run Code Online (Sandbox Code Playgroud)

如果"AAA"或"ZZZ"中不存在,则上面将返回空字符串your_text.

PS Python挑战赛?

  • 这个答案可能值得投票.字符串方法是最强大的方法.它不需要try/except. (4认同)

inf*_*red 14

import re
print re.search('AAA(.*?)ZZZ', 'gfgfdAAA1234ZZZuijjk').group(1)
Run Code Online (Sandbox Code Playgroud)

  • `AttributeError: 'NoneType' 对象没有属性 'groups'` - 如果字符串中没有 AAA、ZZZ... (4认同)

小智 9

您可以只使用一行代码

>>> import re

>>> re.findall(r'\d{1,5}','gfgfdAAA1234ZZZuijjk')

>>> ['1234']
Run Code Online (Sandbox Code Playgroud)

结果将收到清单...


Unc*_*air 9

令人惊讶的是没有人提到这是我一次性脚本的快速版本:

>>> x = 'gfgfdAAA1234ZZZuijjk'
>>> x.split('AAA')[1].split('ZZZ')[0]
'1234'
Run Code Online (Sandbox Code Playgroud)


Fer*_*ann 8

text = 'I want to find a string between two substrings'
left = 'find a '
right = 'between two'

print(text[text.index(left)+len(left):text.index(right)])
Run Code Online (Sandbox Code Playgroud)

给予

string
Run Code Online (Sandbox Code Playgroud)


and*_*opp 7

您可以使用re模块:

>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
('1234,)
Run Code Online (Sandbox Code Playgroud)


小智 6

>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
Run Code Online (Sandbox Code Playgroud)


ras*_*hok 6

在python中,可以使用findall正则表达式( re)模块中的方法来提取子串形式的字符串。

>>> import re
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> ss = re.findall('AAA(.+)ZZZ', s)
>>> print ss
['1234']
Run Code Online (Sandbox Code Playgroud)


Avi*_*Raj 5

使用sed可以使用字符串执行类似的操作:

echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"

结果这将给我1234.

您可以re.sub使用相同的正则表达式执行相同的功能.

>>> re.sub(r'.*AAA(.*)ZZZ.*', r'\1', 'gfgfdAAA1234ZZZuijjk')
'1234'
Run Code Online (Sandbox Code Playgroud)

在基本的sed中,捕获组由表示\(..\),但在python中它由表示(..).


Sae*_*odi 5

您可以在代码中使用此函数找到第一个子字符串(按字符索引)。此外,您还可以找到子字符串后面的内容。

def FindSubString(strText, strSubString, Offset=None):
    try:
        Start = strText.find(strSubString)
        if Start == -1:
            return -1 # Not Found
        else:
            if Offset == None:
                Result = strText[Start+len(strSubString):]
            elif Offset == 0:
                return Start
            else:
                AfterSubString = Start+len(strSubString)
                Result = strText[AfterSubString:AfterSubString + int(Offset)]
            return Result
    except:
        return -1

# Example:

Text = "Thanks for contributing an answer to Stack Overflow!"
subText = "to"

print("Start of first substring in a text:")
start = FindSubString(Text, subText, 0)
print(start); print("")

print("Exact substring in a text:")
print(Text[start:start+len(subText)]); print("")

print("What is after substring \"%s\"?" %(subText))
print(FindSubString(Text, subText))

# Your answer:

Text = "gfgfdAAA1234ZZZuijjk"
subText1 = "AAA"
subText2 = "ZZZ"

AfterText1 = FindSubString(Text, subText1, 0) + len(subText1)
BeforText2 = FindSubString(Text, subText2, 0) 

print("\nYour answer:\n%s" %(Text[AfterText1:BeforText2]))
Run Code Online (Sandbox Code Playgroud)


Rap*_*ael 5

使用 PyParsing

import pyparsing as pp

word = pp.Word(pp.alphanums)

s = 'gfgfdAAA1234ZZZuijjk'
rule = pp.nestedExpr('AAA', 'ZZZ')
for match in rule.searchString(s):
    print(match)
Run Code Online (Sandbox Code Playgroud)

产生:

[['1234']]


coo*_*ter 5

Python 3.8 if 的一个衬垫text保证包含子字符串:

text[text.find(start:='AAA')+len(start):text.find('ZZZ')]
Run Code Online (Sandbox Code Playgroud)