假设我有一个字符串'gfgfdAAA1234ZZZuijjk'
,我只想提取'1234'
部分。
我只知道AAA
之前的几个字符是什么,以及ZZZ
我感兴趣的1234
之后的部分。
使用sed
可以使用字符串执行类似的操作:
echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"
结果这会给我1234
。
如何在Python中做同样的事情?
答案 0 :(得分:437)
使用正则表达式 - documentation进一步参考
import re
text = 'gfgfdAAA1234ZZZuijjk'
m = re.search('AAA(.+?)ZZZ', text)
if m:
found = m.group(1)
# found: 1234
或:
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
答案 1 :(得分:93)
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> start = s.find('AAA') + 3
>>> end = s.find('ZZZ', start)
>>> s[start:end]
'1234'
如果您愿意,也可以将regexps与re模块一起使用,但在您的情况下这不是必需的。
答案 2 :(得分:42)
import re
re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)
如果AttributeError
your_text
your_text.partition("AAA")[2].partition("ZZZ")[0]
如果your_text
中不存在“AAA”或“ZZZ”,则上述内容将返回空字符串。
PS Python挑战赛?
答案 3 :(得分:13)
import re
print re.search('AAA(.*?)ZZZ', 'gfgfdAAA1234ZZZuijjk').group(1)
答案 4 :(得分:7)
您可以使用re模块:
>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
('1234,)
答案 5 :(得分:5)
使用sed可以使用字符串执行类似的操作:
echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*|\1|"
结果这将给我1234。
您可以使用相同的正则表达式对re.sub
函数执行相同的操作。
>>> re.sub(r'.*AAA(.*)ZZZ.*', r'\1', 'gfgfdAAA1234ZZZuijjk')
'1234'
在基本sed中,捕获组由\(..\)
表示,但在python中,它由(..)
表示。
答案 6 :(得分:5)
你可以只使用一行代码
>>> import re
>>> re.findall(r'\d{1,5}','gfgfdAAA1234ZZZuijjk')
>>> ['1234']
结果将收到列表......
答案 7 :(得分:4)
您可以在代码中找到第一个带有此函数的子字符串(按字符索引)。此外,您可以找到子字符串后面的内容。
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]))
答案 8 :(得分:3)
在python中,可以使用正则表达式(findall
)模块中的re
方法来提取子字符串表单字符串。
>>> import re
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> ss = re.findall('AAA(.+)ZZZ', s)
>>> print ss
['1234']
答案 9 :(得分:2)
以防万一有人必须做同样的事情。我必须在一行中提取括号内的所有内容。例如,如果我有一条像“美国总统(巴拉克奥巴马)会见......那样的线路”,我想只得到'巴拉克奥巴马',这就是解决方案:
regex = '.*\((.*?)\).*'
matches = re.search(regex, line)
line = matches.group(1) + '\n'
即。你需要用slash \
符号来阻止括号。虽然这是Python的更多正则表达式的问题。
此外,在某些情况下,您可能会在正则表达式定义之前看到'r'符号。如果没有r前缀,则需要使用C中的转义字符。Here对此进行更多讨论。
答案 10 :(得分:2)
>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
答案 11 :(得分:2)
令人惊讶的是,没有人提到这是我一次性脚本的快速版本:
>>> x = 'gfgfdAAA1234ZZZuijjk'
>>> x.split('AAA')[1].split('ZZZ')[0]
'1234'
答案 12 :(得分:2)
使用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)
产生:
[['1234']]
答案 13 :(得分:1)
一个带有 Python 3.8 的衬垫:
text[text.find(start:='AAA')+len(start):text.find('ZZZ')]
答案 14 :(得分:0)
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)])
给予
string
答案 15 :(得分:0)
另一种使用列表的方式(假设您要查找的子字符串仅由数字组成):
string = 'gfgfdAAA1234ZZZuijjk'
numbersList = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
output = []
for char in string:
if char in numbersList: output.append(char)
print(f"output: {''.join(output)}")
### output: 1234
答案 16 :(得分:0)
这是不带正则表达式的解决方案,它也解决了第一个子字符串包含第二个子字符串的情况。仅当第二个标记位于第一个标记之后,此函数才会找到子字符串。
def find_substring(string, start, end):
len_until_end_of_first_match = string.find(start) + len(start)
after_start = string[len_until_end_of_first_match:]
return string[string.find(start) + len(start):len_until_end_of_first_match + after_start.find(end)]
答案 17 :(得分:0)
打字稿。在其他两个字符串之间获取字符串。
搜索前缀和后缀之间的最短字符串
前缀-字符串/字符串数组/空(意味着从头开始搜索)。
后缀-字符串/字符串数组/ null(表示搜索到最后)。
public getStringInBetween(str: string, prefixes: string | string[] | null,
postfixes: string | string[] | null): string {
if (typeof prefixes === 'string') {
prefixes = [prefixes];
}
if (typeof postfixes === 'string') {
postfixes = [postfixes];
}
if (!str || str.length < 1) {
throw new Error(str + ' should contain ' + prefixes);
}
let start = prefixes === null ? { pos: 0, sub: '' } : this.indexOf(str, prefixes);
const end = postfixes === null ? { pos: str.length, sub: '' } : this.indexOf(str, postfixes, start.pos + start.sub.length);
let value = str.substring(start.pos + start.sub.length, end.pos);
if (!value || value.length < 1) {
throw new Error(str + ' should contain string in between ' + prefixes + ' and ' + postfixes);
}
while (true) {
try {
start = this.indexOf(value, prefixes);
} catch (e) {
break;
}
value = value.substring(start.pos + start.sub.length);
if (!value || value.length < 1) {
throw new Error(str + ' should contain string in between ' + prefixes + ' and ' + postfixes);
}
}
return value;
}
答案 18 :(得分:-1)
如果没有匹配,则返回其他字符串的一个内容。
修改:改进版使用next
函数,如果需要,请将"not-found"
替换为其他内容:
import re
res = next( (m.group(1) for m in [re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk" ),] if m), "not-found" )
我这样做的另一种方法,不太理想,第二次使用正则表达式,仍然没有找到更短的方法:
import re
res = ( ( re.search("AAA(.*?)ZZZ", "gfgfdAAA1234ZZZuijjk") or re.search("()","") ).group(1) )