【问题标题】:Why do both the if and elif statements perform in my python code?为什么 if 和 elif 语句都在我的 python 代码中执行?
【发布时间】:2021-04-02 00:27:43
【问题描述】:

我正在尝试打开一个 XML 文件并对其进行解析,查看其标签并在每个特定标签中查找文本。如果标记中的文本与字符串匹配,我希望它删除字符串的一部分或用其他内容替换它。

但是,由于某种原因,我的“if 语句”似乎不起作用。我希望它仅在变量“action”等于“remove”时才执行某些操作,并且仅在变量“action”等于“substitute”时执行其他操作。但是,当“action”等于“substitute”时,if 语句将执行还有 elif 语句中的内容。此外,第二个 if 语句中的 if、elif 和 else 语句似乎也不起作用。即使 end_int 不等于 none,if 语句中的内容也会发生但不会继续“start_int == None”和其余情况下的 elif 和 else 语句。

mfn_pn 变量是用户输入的条形码,类似于 ATL-157-1815、DFW-184-8378.、ATL-324-3243.、DFW-432-2343。

XML 文件有以下数据:

<?xml version="1.0" encoding="utf-8"?>
<metadata>
    <filter>
        <regex>ATL|LAX|DFW</regex >
        <start_char>3</start_char>
        <end_char></end_char>
        <action>remove</action>
    </filter>
    <filter>
        <regex>DFW.+\.$</regex >
        <start_char>3</start_char>
        <end_char>-1</end_char>
        <action>remove</action>
    </filter>
    <filter>
        <regex>\-</regex >
        <replacement></replacement>
        <action>substitute</action>
    </filter>
    <filter>
        <regex>\s</regex >
        <replacement></replacement>
        <action>substitute</action>
    </filter>
    <filter>
        <regex> T&amp;R$</regex >
        <start_char></start_char>
        <end_char>-4</end_char>
        <action>remove</action>
    </filter>
</metadata>

我使用的 Python 代码是:

from xml.etree.ElementTree import ElementTree

# filters.xml is the file that holds the things to be filtered
tree = ElementTree()
tree.parse("filters.xml")

# Get the data in the XML file 
root = tree.getroot()

# Loop through filters
for x in root.findall('filter'):

    # Find the text inside the regex tag
    regex = x.find('regex').text

    # Find the text inside the start_char tag
    start_prim = x.find('start_char')
    
    # If the element exists assign its text to start variable
    start = start_prim.text if start_prim is not None else None
    start_int = int(start) if start is not None else None

    # Find the text inside the end_char tag
    end_prim = x.find('end_char')

    # If the element exists assign its text end variable
    end = end_prim.text if end_prim is not None else None
    end_int = int(end) if end is not None else None

    # Find the text inside the action tag
    action = x.find('action').text

    if action == 'remove':
        if re.match(r'%s' % regex, mfn_pn, re.IGNORECASE):
            if end_int == None:
                mfn_pn = mfn_pn[start_int:]
            elif start_int == None:
                mfn_pn = mfn_pn[:end_int]
            else: 
                mfn_pn = mfn_pn[start_int:end_int]
                
    elif action == 'substitute':
        mfn_pn = re.sub(r'%s' % regex, '', mfn_pn)

输出:

如果 mfn_pn = 1PDFW 356-5789,我得到 FW3565789。它删除前 3 个字符,即使它应该查看 xml 文件并且当 regex 等于 1P 时,只删除前两个字符,因为 start_char 等于 2。所以 mfn_pn = regex[start_int:] 应该是 mfn_pn = regex[ 2:],但由于某种原因它仍然认为 start_int 是 3。

如果 mfn_pn = DFW 356-5789,我得到 3565789。它正在删除前三个字符,即使正则表达式与任何应该删除的字符都不匹配 - 它会执行 if 语句,即使它应该跳过到 elif 语句。

似乎只获取第一个“过滤器”标签中的内容并将正则表达式设置为仅等于第一个正则表达式标签中的内容,start_int 等于仅第一个 start_int 中的内容,end_char 等于仅第一个 end_int 中的内容.在 if 语句中,它不会将正则表达式设置为等于剩余过滤器标签中的内容。

【问题讨论】:

  • 尝试将其减少为minimal reproducible example。您是否尝试过在代码中的不同位置添加 print 语句以使其向您揭示相关变量的确切内容?
  • 'mfn_pn' 对象未在代码中赋值
  • 是的,我放了打印语句来测试它。 if 和 elif 语句都执行,即使我认为它会是其中之一。此外,对于 if、elif 和 else,只有 if 语句中的内容才会发生。就好像它认为 end_int = 总是 None,即使它不是。
  • 更新你的问题,所以代码是。 minimal reproducible example - 包括设置 mfn_pn,执行您提到的所有显示路径的打印,即在 if 中添加 print(f”remove {action=}”) 用于删除,在 elif 中添加 print(f”substitute {action=}”) 用于替代,并在每个 if/elif 的末尾,并在末尾打印 mfn_pn。
  • 你要做的就是看看你假设的任何东西,比如(说)“哦,当然 re.match 匹配”并证明/错误证明这些假设 - 例如在内部 if 语句中,打印正在测试的值和结果,以便您确认您的假设。这叫调试。

标签: python xml for-loop if-statement variables


【解决方案1】:

根据您想要的 1PDFW 356-5789 的输出,它将产生 3565789。如果可以更改正则表达式,我对 filters.xml 和 python 代码有如下建议

XML 文件有以下数据:

<?xml version="1.0" encoding="utf-8"?>
<metadata>
    <filter>
        <regex>ATL|LAX|DFW</regex >
        <start_char>2</start_char>
        <end_char></end_char>
        <action>remove</action>
    </filter>
    <filter>
        <regex>DFW</regex >
        <start_char>3</start_char>
        <end_char></end_char>
        <action>remove</action>
    </filter>
    <filter>
        <regex>\-</regex >
        <replacement></replacement>
        <action>substitute</action>
    </filter>
    <filter>
        <regex>\s</regex >
        <replacement></replacement>
        <action>substitute</action>
    </filter>
    <filter>
        <regex> T&amp;R$</regex >
        <start_char></start_char>
        <end_char>-4</end_char>
        <action>remove</action>
    </filter>
</metadata>

我使用的 Python 代码是:

import re
from xml.etree.ElementTree import ElementTree

# filters.xml is the file that holds the things to be filtered
tree = ElementTree()
tree.parse("filter.xml")

# Get the data in the XML file
root = tree.getroot()

# Loop through filters
for x in root.findall('filter'):

    # Find the text inside the regex tag
    regex = x.find('regex').text

    # Find the text inside the start_char tag
    start_prim = x.find('start_char')

    # If the element exists assign its text to start variable
    start = start_prim.text if start_prim is not None else None
    start_int = int(start) if start is not None else None

    # Find the text inside the end_char tag
    end_prim = x.find('end_char')

    # If the element exists assign its text end variable
    end = end_prim.text if end_prim is not None else None
    end_int = int(end) if end is not None else None

    # Find the text inside the action tag
    action = x.find('action').text
    if action == 'remove':
        if re.search(r'%s\b' % regex,mfn_pn):
            mfn_pn = mfn_pn[start_int:end_int]

    elif action == 'substitute':
        mfn_pn = re.sub(r'%s' % regex, '', mfn_pn)

【讨论】:

  • 我在代码的不同部分声明了 mfn_pn。这是上面问题中提到的用户输入。我没有在此处包含它以使问题最小化。我想要代码的 re.max 部分中的内容来更改 mfn_pn。我知道它可以工作,因为我使用 print 语句进行检查,只是它没有循环遍历整个 if/elif 语句。
  • 索菲亚,不要夸大“最小”。改为使用minimal reproducible example。您会看到否则会出现哪些问题。
  • 我不知道如何添加一个最小的可重现示例,而不会遗漏一些东西,也不会解决我的问题。
  • 也许你可以举一个你想要的输出的例子,以及当前代码是如何输出的
  • @Irvan Ariyanto 我已经更新了我的问题以在最后添加输出。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-26
  • 1970-01-01
  • 2017-07-02
相关资源
最近更新 更多