在python中,如何“如果finditer(...)没有匹配项”?

时间:2019-05-08 23:13:58

标签: python regex

当finditer()找不到任何东西时,我想做些什么。

import re
pattern = "1"
string = "abc"  
matched_iter = re.finditer(pattern, string)
# <if matched_iter is empty (no matched found>.
#   do something.
# else
    for m in matched_iter:
        print m.group()

我想出的最好的办法是手动跟踪找到的内容:

mi_no_find = re.finditer(r'\w+',"$$%%%%")   # not matching.
found = False
for m in mi_no_find:
    print m.group()
    found = True
if not found:
    print "Nothing found"

不回答的相关帖子:

[edit]
-我对枚举或计数总输出没有兴趣。只有找到了,否则才找到动作。
-我知道我可以将finditer放入列表中,但这对于大型字符串而言效率不高。一个目标是降低内存利用率。

4 个答案:

答案 0 :(得分:3)

如果性能不是问题,只需使用findalllist(finditer(...)),它们就会返回一个列表。

否则,您可以使用next“窥视”生成器,然后在生成StopIteration时正常循环。尽管还有其他方法可以做到,但这对我来说是最简单的:

import itertools
import re

pattern = "1"
string = "abc"  
matched_iter = re.finditer(pattern, string)

try:
    first_match = next(matched_iter)
except StopIteration:
    print("No match!") # action for no match
else:
    for m in itertools.chain([first_match], matched_iter):
        print(m.group())

答案 1 :(得分:3)

您可以使用next探测迭代器,然后将chain的结果放回一起,而StopIteration除外,这意味着迭代器为空:

import itertools as it

matches = iter([])
try:
    probe = next(matches)
except StopIteration:
    print('empty')
else:
    for m in it.chain([probe], matches):
        print(m)

关于您的解决方案,您可以直接检查m,并将其预先设置为None

matches = iter([])
m = None
for m in matches:
    print(m)
if m is None:
    print('empty')

答案 2 :(得分:1)

更新了04/10/2020

使用re.search(pattern, string)检查模式是否存在。

pattern = "1"
string = "abc"

if re.search(pattern, string) is None:
    print('do this because nothing was found')

返回:

do this because nothing was found

如果您希望遍历收益 ,则将re.finditer()放在re.search()内。

pattern = '[A-Za-z]'
string = "abc"

if re.search(pattern, string) is not None:
    for thing in re.finditer(pattern, string):
        print('Found this thing: ' + thing[0])

返回:

Found this thing: a
Found this thing: b
Found this thing: c

因此,如果您想同时使用这两个选项,请在else:条件下使用if re.search()子句。

pattern = "1"
string = "abc"

if re.search(pattern, string) is not None:
    for thing in re.finditer(pattern, string):
        print('Found this thing: ' + thing[0])
else:
    print('do this because nothing was found')

返回:

do this because nothing was found

下面的上一个答复(不够,仅需在上面阅读)

如果.finditer()与模式不匹配,则它将在相关循环内不执行任何命令。

所以:

  • 在循环之前在循环中设置变量
  • 在您用来迭代正则表达式返回的循环之后(在循环之外)调用变量

这样,如果正则表达式调用未返回任何内容,则循环将不会执行,并且循环后的变量调用将返回与设置相同的变量。

下面的示例1演示了正则表达式查找模式。示例2显示了正则表达式找不到模式,因此循环中的变量从未设置。 示例3 显示了我的建议-在regex循环之前设置变量,因此,如果regex找不到匹配项(随后不触发循环),循环后的变量调用返回初始变量集(确认未找到正则表达式模式)。

请记住要导入 import re 模块。

示例1(在字符串“ hello world”中搜索字符“ he”将返回“ he”)

my_string = 'hello world'
pat = '(he)'
regex = re.finditer(pat,my_string)

for a in regex:
    b = str(a.groups()[0])
print(b)

# returns 'he'

示例2(在字符串“ hello world”中搜索字符“ ab”不匹配任何内容,因此“ for a in regex:”循环不会执行,并且不会为b变量分配任何值。)< / p>

my_string = 'hello world'
pat = '(ab)'
regex = re.finditer(pat,my_string)

for a in regex:
    b = str(a.groups()[0])
print(b)

# no return

示例3(再次搜索字符'ab',但这一次将变量b设置为循环前的'CAKE',然后在循环外调用变量b返回初始变量-即'CAKE' -由于循环未执行)。

my_string = 'hello world'
pat = '(ab)'
regex = re.finditer(pat,my_string)

b = 'CAKE' # sets the variable prior to the for loop
for a in regex:
    b = str(a.groups()[0])
print(b) # calls the variable after (and outside) the loop

# returns 'CAKE'

还值得注意的是,在设计要输入到正则表达式的模式时,请确保使用括号指示组的开始和结束。

pattern = '(ab)' # use this
pattern = 'ab' # avoid using this

要回答最初的问题:

由于没有发现任何内容不会执行for循环(对于regex中的for),用户可以预先加载变量,然后在for循环后检查该变量是否为原始加载值。这将使用户知道是否未找到任何内容。

my_string = 'hello world'
pat = '(ab)'
regex = re.finditer(pat,my_string)

b = 'CAKE' # sets the variable prior to the for loop
for a in regex:
    b = str(a.groups()[0])
if b == ‘CAKE’:
    # action taken if nothing is returned

答案 3 :(得分:0)

如果字符串中没有匹配项,它将打印原始字符串。 它将替换字符串的位置n

有关更多参考:https://docs.python.org/2/howto/regex.html



Input_Str = "FOOTBALL"

def replacing(Input_String, char_2_replace, replaced_char, n):
    pattern = re.compile(char_2_replace)
    if len(re.findall(pattern, Input_String)) >= n: 
        where = [m for m in pattern.finditer(Input_String)][n-1]
        before = Input_String[:where.start()]
        after = Input_String[where.end():]
        newString = before + replaced_char + after
    else: 
        newString = Input_String
    return newString

print(replacing(Input_Str, 'L', 'X', 4))```