我怀疑 re.match 弄乱了控制流

Posted

技术标签:

【中文标题】我怀疑 re.match 弄乱了控制流【英文标题】:I suspect that re.match messing up control flow 【发布时间】:2011-12-12 01:13:26 【问题描述】:

if 块内的正则表达式匹配是否会干扰 else 块内的代码?

在下面的代码中,我有 100 个测试字符串作为job_name 输入,应该附加到我的del_job_ids 数组中。其中只有 99 个被附加。

for j in jobs:
     name = jobs[j]['Job_Name'][0]       
     p=re.compile("(\\w*):?\\w*-?\\d*")
     if ((':' in name) or ('-' in name)):
         name=p.match(name).group(1)
     else:
         #if name==job_name and state!='C':
         #print "ok" 
         #del_job_ids.append(j)
         pass
     if name==job_name and state!='C':
         del_job_ids.append(j)
         name=None

如果我注释掉行 name=p.match(name).group(1),那么之前没有附加的一种情况现在会附加。我还可以通过取消注释 else 块中的代码来附加该作业(字符串通过了附加条件)。

字符串之间的区别在于,其中 99 个字符串有冒号、破折号或两者都有,而另一个字符串则没有。我多次测试了正则表达式。没有破折号或冒号的字符串应该放在 else 子句中,并使用在 for 循环顶部定义的“默认”名称。

【问题讨论】:

请发布一些有效的示例字符串,以及一个无效的字符串。 作品:training_2-1, training_2:o-25, Training_2:a;不:training_2 【参考方案1】:

你在这里做了一些非常奇怪的事情。让我们来看看其中的几个。

1 - name = jobs[j]['Job_Name'][0]

在我看来,jobs 可能是一个字典容器,它有一个键“Job_Name”,而该键的值是一个列表或元组。我想你可能的意思是:

name = j['Job_name'][0]

如果作业只是一个字符串列表,即作业名称,那么您只需要以下内容: name = j,你可以跳过它——当你想引用它时,只需使用j

2 - p=re.compile("(\\w*):?\\w*-?\\d*")

您每次通过循环时都在编译您的正则表达式,每次都完全相同,并且您使用它一次循环开始之前进行编译。

3 - 你根本不需要你的 else 子句。如果你想在 Python 中使用“else if”,你可以使用“elif”。

4 - 您的正则表达式可以通过使用 raw 字符串来消除所有双重转义符来简化:p=re.compile(r"(\w*):?\w*-?\d*")

5 - 你的整个正则表达式可能是不必要的。如果您正在做我认为您正在做的事情,那么您只需要出现在第一个冒号之前的内容(如果有的话)。 (除非你真的是指group(1),我认为你不是。)这意味着你可以跳过正则表达式(因为你无论如何都与in匹配),只需使用name = name.split(':')[0]之类的东西

【讨论】:

【参考方案2】:
name=p.match(name).group(1)

你正在改变 name 是什么。这可能是错误的:

if name==job_name and state!='C':

这使得该语句不执行:

del_job_ids.append(j)

我建议看看namename.p.match(name).group(1) 语句之后是什么。

【讨论】:

也许我遗漏了一些东西......每次 for 循环运行时,都应该更新名称。此外,没有附加的情况由 else 块处理。 @thaiyoshi - 你的else 块中的所有代码都被注释掉了。 应该注释掉。 else 块仅用于测试。 else 情况应使用 name = jobs[j]['Job_Name'][0]。 @thaiyoshi - 我的意思是您正在更改name,这使得name==job_name and state!='C' 变为False,因此它不会执行该块。您需要弄清楚此时 name 是什么以及它与该语句不匹配的原因。问题不在于正则表达式,而在于代码中的其余逻辑。【参考方案3】:
 for j in jobs:
      name = jobs[j]['Job_Name'][0]

这部分对我来说没有意义。如果 'jobs' 是可迭代的,那么第一次通过循环时,'j' 设置为 'jobs[0]',下一次设置为 'jobs[1]',等等。所以使用 'j' 来对“工作”的索引是疯狂的谈话。你是说“给我可迭代的‘jobs’中的下一个元素,然后使用该元素作为‘jobs’的索引。

【讨论】:

好点。我怀疑jobs 是一本字典,所以他们真正想要的是for job in jobs.values(): name = job["Job_Name"][0](当然,job["Job_Name"][0] 暗示了更多的问题..)【参考方案4】:

match() 不会“干扰” else 子句。

这里最可能的原因是 name==job 条件在您的一个测试用例中失败。

明智地使用打印语句可能会显示跳过了哪个字符串。或者你使用 pdb.

【讨论】:

没有通过的情况由 else 子句处理。将 name==job 条件放在 else 子句中使其通过。

以上是关于我怀疑 re.match 弄乱了控制流的主要内容,如果未能解决你的问题,请参考以下文章

自动布局弄乱了我的动画

UITextField 子类弄乱了adjustFontSizeToWidth

为啥 QTextBrowser 弄乱了我的 HTML 代码?

为啥我的 div 被平板电脑上的表格弄乱了?

Perl 5.10 是不是把原型弄乱了?

Php 弄乱了我的上传大小