【问题标题】:How to partial search for words using regex python如何使用正则表达式 python 部分搜索单词
【发布时间】:2018-08-30 18:33:49
【问题描述】:

我想获取在某处有“反馈报告”的所有“xlsx”文件。我想让这个过滤器非常强大。所以任何部分匹配,如“feedback_report”、“feedback report”、“Feedback Report”都应该返回 true。

示例文件名:

  1. ZSS 项目_JKIAL-SA_FEEDBACK_REPORT_2015 年 1 月 29 日.xlsx
  2. ZL-SA_feedback report_012844.xlsx
  3. ASARanem-SA_Feedback Report_012844.xlsx

下面是徒劳的尝试。

regex = re.compile(r"[a-zA-Z0-0]*[fF][eE][eE][dD][bB][aA][cC][kK]\s[rR][eE][pP][oO][rR][tT][a-zA-Z0-0]*.xlsx")

【问题讨论】:

  • 我不是 python 开发人员,但 .*feedback[\s_]report.*\.xlsx 似乎与 IGNORECASE 选项就足够了。
  • 是的,你是绝对正确的,它减少了这个线程上每个人指出的很多排列。

标签: python regex word


【解决方案1】:

这将起作用:

re.search("(feedback)(.*?|\s)(report)",string,re.IGNORECASE)

使用代码在以下输入列表中对其进行了测试

import re
a=["ZSS Project_JKIAL-SA_FEEDBACK_REPORT_Jan 29th 2015.xlsx",
"ZL-SA_feedback report_012844.xlsx",
"ASARanem-SA_Feedback Report_012844.xlsx",
"some report",
"feedback-report"]

for i in a:
    print(re.search("(feedback)(.*?|\s)(report)",i,re.IGNORECASE))

OP 预期的输出是:

<_sre.SRE_Match object; span=(21, 36), match='FEEDBACK_REPORT'>
<_sre.SRE_Match object; span=(6, 21), match='feedback report'>
<_sre.SRE_Match object; span=(12, 27), match='Feedback Report'>
None
<_sre.SRE_Match object; span=(0, 15), match='feedback-report'>

【讨论】:

    【解决方案2】:

    您的正则表达式几乎可以接受,但开头和结尾部分将无法正确匹配,因为您的示例中有下划线。我不确定这些对您的实际数据有多大的代表性,但要与您在这里的数据相匹配,您需要:

    regex = re.compile(r"[a-zA-Z0-0\_\-\s]*(feedback)[\s\_\-](report)[a-zA-Z0-0\_\-\s]*.xlsx", 
        flags = re.IGNORECASE)
    

    您可能应该注意的另一件事是确保您实际上只使用文件名而不是文件路径,因为在这种情况下您必须担心\/ 字符。另请注意,我只匹配我注意到您丢失的确切字符。你可以试试

    regex = re.compile(r"*(feedback)*(report)*.xlsx", flags = re.IGNORECASE)
    

    但是,同样,我不确定您的数据实际上是什么样的。希望这会有所帮助

    【讨论】:

      【解决方案3】:

      首先,小写文件名以尽量减少可能的选项数量

      regex = re.compile('feedback.{0,3}report.*\.xlsx?', flags=re.IGNORECASE)
      

      查找“反馈”,接下来最多 3 个字符,下一个“报告”,然后再查找,以点和 xls 或 xlsx 扩展名结尾

      或者只是

      filename = 'ZL-SA_feedback report_012844.xlsx'
      matched = re.search('feedback.{0,3}report.*\.xlsx?', filename.lower())
      

      您也可以使用 python glob 模块以 linux 方式搜索文件:

      import glob
      glob.glob('*[fF][eE][dD][bB][aA][cC][kK]*[rR][eE][pP][oO][rR][tT]*.xlsx')
      

      【讨论】:

        【解决方案4】:

        您可以只使用如下字符串方法吗?

        'feedbackreport' in name.replace('_', '').replace(' ', '').lower()
        

        还有

        name.endswith('.xlsx')
        

        给你类似的东西:

        fileList = [
            'ZSS Project_JKIAL-SA_FEEDBACK_REPORT_Jan 29th 2015.xlsx',
            'ZL-SA_feedback report_012844.xlsx',
            'ASARanem-SA_Feedback Report_012844.xlsx'
        ]
        
        fileNames = [name for name in fileList
                     if ('feedbackreport' in name.replace('_', '').replace(' ', '').lower()
                         and name.endswith('.xlsx'))]
        

        如果有更多字符可能导致问题,例如-,那么您还可以创建一个快速函数来删除坏字符:

        def remove_bad_chars(string, chars): 
            for char in chars:
                string = string.replace(char, '')
            return string
        

        将 if 语句的适当部分修改为:

        if 'feedbackreport' in remove_bad_chars(name, '.,?!\'-/:;()"\\~ ').lower()
        # included a white space in the string of bad characters
        

        【讨论】:

        • 这行不通,因为strip 只会删除前导和尾随空格
        【解决方案5】:

        根据您的所有建议,我将它用于我的字符串。这在 99% 的情况下都适用于我。

        regex = re.compile(r"[a-zA-Z0-9\_\-\s]*(feedback)(\s|\_)(report)s?[a-zA-Z0-9\_\-\s]*.xlsx",flags = re.IGNORECASE)
        

        【讨论】:

          猜你喜欢
          • 2012-03-10
          • 2015-03-16
          • 1970-01-01
          • 1970-01-01
          • 2020-01-25
          • 1970-01-01
          • 2011-10-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多