【问题标题】:Python Regular Expression to find all combinations of a Letter Number Letter DesignationPython正则表达式查找字母数字字母名称的所有组合
【发布时间】:2013-10-27 17:26:52
【问题描述】:

我需要实现一个 Python 正则表达式来搜索所有出现的 A1aA_1_aA-1-a_A_1_a__A1a,其中:

  • A 可以是A到Z
  • 1 可以是1 到 9
  • a 可以是a 到 z

其中只有三个字符的字母数字字母,用下划线、破折号或什么都没有分隔。搜索字符串中的大小写需要完全匹配。

我遇到的主要问题是,有时这三个字母组合通过破折号和下划线连接到其他文本。还创建相同的正则表达式来搜索A1aA-1-aA_1_a

另外我忘了说这是一个 XML 文件。

感谢这找到了我正在寻找的每一次轻微修改 [-]?[A][-]?[1][-]?[a][-]?,但我需要这些是变量,比如

    [-]?[var_A][-]?[var_3][-]?[Var_a][-]? 

会这样吗

    regex = r"[-]?[%s][-]?[%s][-]?[%s][-]?" 
    print re.findall(regex,var_A,var_Num,Var_a)

或者更像:

    regex = ''.join(['r','\"','[-]?[',Var_X,'][-]?[',Var_Num,'][-]?[',Var_x,'][-]?','\"'‌​])
    print regex 
    for sstr in searchstrs: 
            matches = re.findall(regex, sstr, re.I)

但这不起作用

文件的示例行: 运行脚本之前

<t:ION t:SA="BoolObj" t:H="2098947" t:P="2098944" t:N="AN7 Result" t:CI="Boolean_Register" t:L="A_3_a  Fdr2" t:VS="true">
<t:ION t:SA="RegisterObj" t:H="20971785" t:P="20971776" t:N="ART1 Result 1" t:CI="NumericVariable_Register" t:L="A3a1 Status" t:VS="1">
<t:ION t:SA="ModuleObj" t:H="2100736" t:P="2097152" t:N="AND/OR 14" t:CI="AndOr_Module" t:L="A_3_a**_2 Energized from Norm" t:S="0" t:SC="5">

运行脚本后 我得到的是:(它正在删除整行,只留下下面的内容)

  • B_1_c
  • B1c1
  • B_1_c_2

我想得到什么:

<t:ION t:SA="BoolObj" t:H="2098947" t:P="2098944" t:N="AN7 Result" t:CI="Boolean_Register" t:L="B_1_c  Fdr2" t:VS="true">
<t:ION t:SA="RegisterObj" t:H="20971785" t:P="20971776" t:N="ART1 Result 1" t:CI="NumericVariable_Register" t:L="B1c1 Status" t:VS="1">
<t:ION t:SA="ModuleObj" t:H="2100736" t:P="2097152" t:N="AND/OR 14" t:CI="AndOr_Module" t:L="B_1_c_2 Energized from Norm" t:S="0" t:SC="5">

import re
import os

search_file_name = 'Alarms Test.fwn'
pattern = 'A3a'
fileName, fileExtension = os.path.splitext(search_file_name)
newfilename = fileName + '_' + pattern + fileExtension
outfile = open(newfilename, 'wb')


def find_ext(text):
    matches = re.findall(r'([_-]?[A{1}][_-]?[3{1}][_-]?[a{1}][_-]?)', text)
    records = [m.replace('3', '1').replace('A', 'B').replace('a', 'c') for m in matches]
    if matches:
        outfile.writelines(records)
        return 1
    else:
        outfile.writelines(text)
        return 0


def main():
    success = 0
    count = 0
    with open(search_file_name, 'rb') as searchfile:
        try:
            searchstrs = searchfile.readlines()
            for s in searchstrs:
                success = find_ext(s)
                count = count + success
        finally:
            searchfile.close()

    print count

if __name__ == "__main__":
    main()

【问题讨论】:

  • A1A1A 应该返回什么? IOW,潜在的重叠呢?
  • 你想匹配开头的下划线/破折号吗?换句话说,_A_1_a_ 的匹配项应该是 _A_1_a_ 还是 A_1_a
  • 是的,XMDC_A1a 或 XMDC-A1a 或 XMDC_A1-a XMDC_A_1_a_Current 都在同一个文件中。
  • @rtsnhth 这些解决方案之一对您有用吗?如果是,请接受并关闭问题。

标签: python regex search replace python-2.6


【解决方案1】:

为了在没有标点符号的情况下快速获取A1as,并且不必从捕获的部分重构字符串...

t = '''A1a _B_2_z_ 
A_1_a 
A-1-a 
_A_1_a_ 
_C1c '''

re.findall("[A-Z][0-9][a-z]",t.replace("-","").replace("_",""))

输出:

['A1a', 'B2z', 'A1a', 'A1a', 'A1a', 'C1c']

(但如果您想要从FILE.TXT-2b 捕获,那么您必须小心大多数这些解决方案...)

【讨论】:

    【解决方案2】:

    您想使用以下内容来查找您的匹配项。

    matches = re.findall(r'([_-]?[a-z][_-]?[1-9][_-]?[a-z][_-]?)', s, re.I)
    

    regex101 demo

    如果您要查找匹配项,则去掉所有 -_ 字符,您可以这样做..

    import re
    
    s = '''
    A1a _A_1 A_ A_1_a A-1-a _A_1_a_ _A1a _A-1-A_ a1_a  A-_-5-a
    _A-_-5-A a1_-1 XMDC_A1a or XMDC-A1a or XMDC_A1-a XMDC_A_1_a_ _A-1-A_
    '''
    
    def find_this(text):
        matches = re.findall(r'([_-]?[a-z][_-]?[1-9][_-]?[a-z][_-]?)', text, re.I)
        records = [m.replace('-', '').replace('_', '') for m in matches]
        print records
    
    find_this(s)
    

    输出

    ['A1a', 'A1a', 'A1a', 'A1a', 'A1a', 'A1A', 'a1a', 'A1a', 'A1a', 'A1a', 'A1a', 'A1A']
    

    working demo

    【讨论】:

      【解决方案3】:
      regex = r"[A-Z][-_]?[1-9][-_]?[a-z]"
      print re.findall(regex,some_string_variable)
      

      应该工作

      只捕获您感兴趣的部分,将它们包裹在括号中

      regex = r"([A-Z])[-_]?([1-9])[-_]?([a-z])"
      print re.findall(regex,some_string_variable)
      

      如果下划线或破折号或缺少下划线或破折号必须匹配,否则会返回错误结果,您需要状态机,而正则表达式是无状态的

      【讨论】:

      • 不要忘记前面可能出现的下划线
      • 与 findall 无关(除非他真的想捕捉它......但听起来他真正关心的只是这 3 个字符
      • 作为一个练习,您将如何使用分组来仅捕获 3 个所需的字符,从而规范化返回数据?
      • mridule 怎么样?它会被很好地捕获。 @CDSpace .. 只需在每个感兴趣的地方加上括号:([A-Z])[-_]?([1-9])[-_]?([a-z])
      • 啊你可能是对的......它仍然应该找到所有匹配项并且不会返回任何错误匹配项
      【解决方案4】:

      如果字符串可以用多个下划线或破折号分隔(例如A__1a):

      [_-]*[A-Z][_-]*[1-9][_-]*[a-z]
      

      如果只能有一个或零个下划线或破折号:

      [_-]?[A-Z][_-]?[1-9][_-]?[a-z]
      

      【讨论】:

      • afaik 这将接受非法匹配,例如 A-_-5-a
      • 海报上写着“下划线、破折号或什么都没有。”
      • afaik 他的意思是每个分隔符一个,但你的权利......这是一个可信的声明,我可能是错的,所以 +1
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-01
      相关资源
      最近更新 更多