'gfgfdAAA1234ZZZuijjk'
,而我只想提取'1234'
的一部分。我只知道
AAA
之前的几个字符以及ZZZ
之后我对1234
感兴趣的部分。 br /> 使用
sed
可以用字符串做类似的事情:echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*||"
这样一来,我会得到
1234
。 /> 如何在Python中做同样的事情?
#1 楼
使用正则表达式-文档以供进一步参考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
#2 楼
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> start = s.find('AAA') + 3
>>> end = s.find('ZZZ', start)
>>> s[start:end]
'1234'
然后,如果需要,您也可以将reexps与re模块一起使用,但这在您的情况下不是必需的。
评论
该问题似乎暗示输入文本将始终同时包含“ AAA”和“ ZZZ”。如果不是这种情况,您的答案将严重失败(这意味着它返回的是完全错误的内容,而不是空字符串或引发异常;以“ hello there”为输入字符串)。
–tzot
2011年2月6日在23:46
@ user225312 re方法不是更快吗?
–confused00
16年7月21日在9:25
投票,但为了可维护性,我将使用“ x ='AAA'; s.find(x)+ len(x)”而不是“ s.find('AAA')+ 3”。
– Alex
17年6月21日在8:47
如果在s中找不到任何标记,则s.find将返回-1。切片运算符s [begin:end]将其接受为有效索引,并返回不需要的子字符串。
–ribamar
17年8月28日在15:44
@ confused00查找比重新stackoverflow.com/questions/4901523/…要快得多。
– Claudiu Creanga
5月3日19:30
#3 楼
正则表达式import re
re.search(r"(?<=AAA).*?(?=ZZZ)", your_text).group(0)
如果
AttributeError
中没有“ AAA”和“ ZZZ”,则上述现状将以your_text
失败字符串方法
your_text.partition("AAA")[2].partition("ZZZ")[0]
如果
your_text
中不存在“ AAA”或“ ZZZ”,则上述方法将返回空字符串。PS Python挑战赛?
评论
这个答案可能值得更多投票。字符串方法是最可靠的方法。它不需要try / except。
– ChaimG
2015年12月3日在2:59
不错,虽然有限。分区不是基于正则表达式的,所以它仅在这种情况下有效,因为搜索字符串受固定文字限制
– GreenAsJade
16-2-29在2:07
太好了,非常感谢! -这适用于字符串,不需要正则表达式
– Alex
18年6月8日在11:53
#4 楼
惊讶的是没有人提到这是我一次性脚本的快速版本:>>> x = 'gfgfdAAA1234ZZZuijjk'
>>> x.split('AAA')[1].split('ZZZ')[0]
'1234'
评论
@ user1810100基本上提到,在您发布此帖子之前的5天几乎是...
–约翰
19年3月12日在18:50
向其中添加一个if s.find(“ ZZZ”)> s.find(“ AAA”):避免了如果'ZZZ`不在字符串中的问题,该问题将返回'1234uuijjk'
–萨克森州的罗夫
11月14日20:42
#5 楼
import re
print re.search('AAA(.*?)ZZZ', 'gfgfdAAA1234ZZZuijjk').group(1)
评论
AttributeError:'NoneType'对象没有属性'groups'-如果字符串中没有AAA,ZZZ ...
–eumiro
2011年1月12日上午9:20
#6 楼
您只需使用一行代码即可完成>>> import re
>>> re.findall(r'\d{1,5}','gfgfdAAA1234ZZZuijjk')
>>> ['1234']
结果将收到列表...
#7 楼
您可以为此使用re模块:>>> import re
>>> re.compile(".*AAA(.*)ZZZ.*").match("gfgfdAAA1234ZZZuijjk").groups()
('1234,)
#8 楼
使用sed可以用字符串做类似的事情:
echo "$STRING" | sed -e "s|.*AAA\(.*\)ZZZ.*||"
这将给我1234作为结果。
您可以使用相同的正则表达式对
re.sub
函数执行相同操作。>>> re.sub(r'.*AAA(.*)ZZZ.*', r'', 'gfgfdAAA1234ZZZuijjk')
'1234'
在基本sed中,捕获组由
\(..\)
表示,但在python中由(..)
表示。#9 楼
在python中,可以在正则表达式(findall
)模块中使用re
方法提取子字符串形式的字符串。>>> import re
>>> s = 'gfgfdAAA1234ZZZuijjk'
>>> ss = re.findall('AAA(.+)ZZZ', s)
>>> print ss
['1234']
#10 楼
>>> s = '/tmp/10508.constantstring'
>>> s.split('/tmp/')[1].split('constantstring')[0].strip('.')
#11 楼
您可以在代码中(按字符索引)在此函数中找到第一个子字符串。另外,您可以找到子字符串之后的内容。
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]))
#12 楼
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
#13 楼
以防万一某人必须做与我相同的事情。我必须在一行中提取括号内的所有内容。例如,如果我有一条类似“美国总统(Barack Obama)遇见...”这样的词,而我只想获得“ Barack Obama”,这就是解决方案:regex = '.*\((.*?)\).*'
matches = re.search(regex, line)
line = matches.group(1) + '\n'
即您需要使用
slash \
符号来阻止括号。尽管这是关于使用Python的更多正则表达式的问题。此外,在某些情况下,您可能会在正则表达式定义之前看到“ r”符号。如果没有r前缀,则需要使用C语言中的转义字符。此处有更多讨论。
#14 楼
使用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']]
#15 楼
这是一个不使用正则表达式的解决方案,它也解决了第一个子字符串包含第二个子字符串的情况。如果第二个标记在第一个标记之后,则此函数将仅找到子字符串。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)]
#16 楼
另一种方法是使用列表(假设您要查找的子字符串仅由数字组成):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
#17 楼
打字稿。获取其他两个字符串之间的字符串。
搜索前缀和后缀之间的最短字符串
前缀-字符串/字符串数组/ null(表示从头开始搜索)。
后缀-字符串/字符串数组/ 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 楼
如果没有匹配,则一个衬里返回其他字符串。编辑:改进的版本使用
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) )
评论
如果模式在大多数情况下都匹配,则第二种解决方案更好,因为它比请求许可更容易请求宽恕。
– Bengt
2013年1月14日16:11
索引不是从0开始吗?因此,您将需要使用组(0)而不是组(1)?
–亚历山大
2015年11月8日在22:16
@Alexander,否,group(0)将返回完全匹配的字符串:AAA1234ZZZ,而group(1)将仅返回与第一个组匹配的字符:1234
– Yuurii K
2015年11月12日13:46
@Bengt:为什么?第一种解决方案对我来说似乎很简单,并且具有更少的代码行。
–你好再见
16年7月7日在13:21
在这个表达式中?将+修改为非贪婪,即它将匹配从1到任意次数的次数,但次数尽可能少,只会根据需要扩展。如果没有?,第一个群组会将gfgfAAA2ZZZkeAAA43ZZZonife匹配为2ZZZkeAAA43,但带有?它只会匹配2,然后搜索多个(或将其删除并再次搜索)将匹配43。
–Dom
17年7月19日在8:31