简单/简单的方式来编写类似开关的正则表达式

时间:2015-04-18 09:24:46

标签: python

我是Python的新手,想知道将下面的代码写入python的最佳方法是什么:

if ($line =~ /(\d)/) {
   $a = $1
}
elsif ($line =~ /(\d\d)/) {
   $b = $1
}
elsif ($line =~ /(\d\d\d)/) {
   $c = $1
}

我想要做的是检索一大堆行中每行的特定部分。在python中我所能做的就是如下所示,非常难看。

res = re.search(r'(\d)', line)
if res:
  a = res.group(1)
else:
  res = re.search(r'(\d\d)', line)
  if res:
    b = res.group(1)
  else:
    res = re.search(r'(\d\d\d)', line)
    if res:
      c = res.group(1)

在没有非内置模块的情况下,有没有人知道更好的方法来编写相同的东西?

修改

如果你需要使用非常不同的re解析线,你怎么写? 我的观点是它应该简单,以便任何人都能理解代码在那里做了什么。 在perl中,我们可以写:

if ($line =~ /^this is a sample line (.+) and contain single value$/) {
  $name = $1
}
elsif ($line =~ /^this is another sample: (.+):(.+) two values here$/) {
  ($address, $call) = ($1, $2)
}
elsif ($line =~ /^ahhhh thiiiss isiss (\d+) last sample line$/) {
  $description = $1
}

从我看来,这种perl代码非常简单易懂。

EDIT2: 我在这里找到了相同的讨论:

http://bytes.com/topic/python/answers/750203-checking-string-against-multiple-patterns

所以没有办法像pyl一样简单地编写python ..

3 个答案:

答案 0 :(得分:2)

模式的

顺序非常重要。因为如果使用此(\d)|(\d\d)|(\d\d\d)模式,则仅第一个组将匹配所有数字字符。因此,它不会尝试检查接下来的两种模式,因为仅第一种模式就能找到所有匹配。

res = re.search(r'(\d\d\d)|(\d\d)|(\d)', line)
if res:
    a, b, c = res.group(3), res.group(2), res.group(1)

DEMO

答案 1 :(得分:2)

您可以自己编写一个帮助函数来将匹配结果存储在外部作用域中,这样您就不需要在if语句中重新匹配正则表达式

def search(patt, str): 
    search.result = re.search(patt, str)
    return search.result

if search(r'(\d)', line):
    a = search.result.group(1)
elif search(r'(\d\d)', line):
    b = search.result.group(1)
elif search(r'(\d\d\d)', line):
    c = search.result.group(1)

在python 3.8中,您将能够使用:

if res := re.search(r'(\d)', line):
    a = res.group(1)
elif res := re.search(r'(\d\d)', line):
    b = res.group(1)
elif res := re.search(r'(\d\d\d)', line):
    c = res.group(1)

答案 2 :(得分:0)

类似于perl,除了'elif'而不是'elsif'和':'在测试后没有花括号(由缩进替换)和可选括号。网络上有许多描述Python语句的资源以及更多可以通过谷歌搜索轻松找到的资源。

if re.search(r'(\d)', line):
    a = re.search(r'(\d)', line).group(1)
elif re.search(r'(\d\d)', line):
    b = re.search(r'(\d\d)', line).group(1)
elif re.search(r'(\d\d\d)', line):
    c = re.search(r'(\d\d\d)', line).group(1)

当然,代码的逻辑是有缺陷的,因为'b'和'c'永远不会被设置,但我认为这是你正在寻找的语法。