Python 寻找正则表达式与不同顺序的组的正确方法

Python 寻找正则表达式与不同顺序的组的正确方法,python,regex,Python,Regex,我正在尝试使用python解析许多cobol副本 我有一个从cobol.py中提供的正则表达式修改而来的正则表达式: ^(?P<level>\d{2})\s+(?P<name>\S+).*? (\s+INDEXED BY\s+(?P<indexed_by>\S+))?.*? (\s+REDEFINES\s+(?P<redefines>\S+))?.*? (\s+PIC(TURE)?\s+(?P<pic>\S+))?.*? (\s+OCC

我正在尝试使用python解析许多cobol副本

我有一个从cobol.py中提供的正则表达式修改而来的正则表达式:

^(?P<level>\d{2})\s+(?P<name>\S+).*?
(\s+INDEXED BY\s+(?P<indexed_by>\S+))?.*?
(\s+REDEFINES\s+(?P<redefines>\S+))?.*?
(\s+PIC(TURE)?\s+(?P<pic>\S+))?.*?
(\s+OCCURS\s+(?P<occurs>\d+).?( TIMES)?)?.*?
((?P<comp>)\s+COMP\S+)?.*?
(\s+VALUE\s+(?P<value>\S+).*)?
\.$
我很难处理正则表达式,但我认为我可能会造成混乱,因为我缺少一些基本的东西

需要明确的是:pic组捕获了包含PICTURE语句的所有行,但最后一行除外,因为它位于ocursecapture组之后


非常感谢您的帮助。

尽管如果您必须使用正则表达式,实际的解析器可能最适合这样做,但您不能使用不同的键添加另一个OCCURS组吗?。e、 g

"""
03  AMOUNT-BREAKDOWN        PICTURE 9(8)V99  VALUE ZEROES.
03  AMOUNT-BREAKDOWN-X REDEFINES AMOUNT-BREAKDOWN.
05  FILLER              PICTURE X(3)     VALUE "DEC".
03  MONTH REDEFINES MONTH-TAB  PICTURE X(3) OCCURS 12 TIMES.
03  SUB                 PICTURE 99    VALUE 0.
03  NUMBER-HOLD.
05  NUMB-HOLD       PICTURE X  OCCURS 11 TIMES.
05  FILLER              PICTURE X(5)     VALUE "TEN".
03  DIGIT-TAB2 REDEFINES DIGIT-TAB1.
05  DIGIT-TABLE         OCCURS 10   PICTURE X(5).
03  WK-TEN-MILLION          PICTURE X(5)     VALUE SPACES.
"""
import re
for line in __doc__.split("\n"):
    if len(line) < 1: continue
    m = re.match(
        "^(?P<level>\d{2})\s+(?P<name>\S+).*?"
        "(\s+INDEXED BY\s+(?P<indexed_by>\S+))?.*?"
        "(\s+REDEFINES\s+(?P<redefines>\S+))?.*?"
        "(\s+OCCURS\s+(?P<occurs1>\d+).?( TIMES)?)?.*?"   # <-- occurs1
        "(\s+PIC(TURE)?\s+(?P<pic>\S+))?.*?"
        "(\s+OCCURS\s+(?P<occurs>\d+).?( TIMES)?)?.*?"
        "((?P<comp>)\s+COMP\S+)?.*?"
        "(\s+VALUE\s+(?P<value>\S+).*)?"
        "\.$", line)
    if m:
        print m.groups()
cb2xml 你应该看看。它将解析一个Cobol Copybook并创建一个Xml文件。然后可以用python处理Xml 或任何语言。cb2xml包提供了用python+其他语言处理Xml的基本示例

Cobol:

   01 Ams-Vendor.
       03 Brand               Pic x(3).
       03 Location-details.
          05 Location-Number  Pic 9(4).
          05 Location-Type    Pic XX.
          05 Location-Name    Pic X(35).
       03 Address-Details.
          05 actual-address.
             10 Address-1     Pic X(40).
             10 Address-2     Pic X(40).
             10 Address-3     Pic X(35).
          05 Postcode         Pic 9(4).
          05 Empty            pic x(6).
          05 State            Pic XXX.
       03 Location-Active     Pic X.
cb2xml的输出:

?xml version="1.0" encoding="UTF-8" standalone="no"?>
<copybook filename="cbl2xml_Test110.cbl">
    <item display-length="173" level="01" name="Ams-Vendor" position="1" storage-length="173">
        <item display-length="3" level="03" name="Brand" picture="x(3)" position="1" storage-length="3"/>
        <item display-length="41" level="03" name="Location-details" position="4" storage-length="41">
            <item display-length="4" level="05" name="Location-Number" numeric="true" picture="9(4)" position="4" storage-length="4"/>
            <item display-length="2" level="05" name="Location-Type" picture="XX" position="8" storage-length="2"/>
            <item display-length="35" level="05" name="Location-Name" picture="X(35)" position="10" storage-length="35"/>
        </item>
        <item display-length="128" level="03" name="Address-Details" position="45" storage-length="128">
            <item display-length="115" level="05" name="actual-address" position="45" storage-length="115">
                <item display-length="40" level="10" name="Address-1" picture="X(40)" position="45" storage-length="40"/>
                <item display-length="40" level="10" name="Address-2" picture="X(40)" position="85" storage-length="40"/>
                <item display-length="35" level="10" name="Address-3" picture="X(35)" position="125" storage-length="35"/>
            </item>
            <item display-length="4" level="05" name="Postcode" numeric="true" picture="9(4)" position="160" storage-length="4"/>
            <item display-length="6" level="05" name="Empty" picture="x(6)" position="164" storage-length="6"/>
            <item display-length="3" level="05" name="State" picture="XXX" position="170" storage-length="3"/>
        </item>
        <item display-length="1" level="03" name="Location-Active" picture="X" position="173" storage-length="1"/>
    </item>
</copybook>                
?xml version=“1.0”encoding=“UTF-8”standalone=“否”>
cb2xml的一个有趣应用在

CobolToCsv 该包将Cobol数据文件转换为Csv文件。限制:

  • 不处理重定义/多记录文件
  • Cobol编译器支持的范围相当有限(大型机、GNUCOBL、富士通Cobol)
Cobol2Csv应该能够处理文本文件(+Comp-3)。它可以处理您的一些文件。

PyParsing()是一个很好的模块,可以轻松构建语法。您可以构建一个基本的Copybook语法,并使用PyParsing对其进行解析。然后,您必须进行后期处理,以保留由两位数级别字段表示的树状结构


还可以看看使用PyParsing的Copybook包()。

是的,您缺少一些基本的东西。这永远不会用正则表达式解析源代码。使用解析器。(似乎至少有一个用于Python的COBOL Copybook解析器)-@Tomalak,这段代码是从该模块借用的。这是不完整的,并没有涵盖所有的情况,所以我修改了它。但这正是在该模块中实现的方式。这是一个令人沮丧的问题。如果事情真的过于简单,你可以使用正则表达式来回避,但每当你得到你没有预料到的有效输入时,任何正则表达式解决方案都会崩溃。要回答您的初始问题-regex group order已修复。如果输入的顺序不同,则需要与该顺序匹配的新正则表达式。这会很快变得单调乏味,每次进行修复时,正则表达式都变得越来越无法维护。请查看
cb2xml
()。正是
java
程序将cobol copybook转换为Xml。cb2xml还计算大型机cobol副本的位置/长度。有一个处理用pythonI编写的Xml的基本示例,我想到了这一点,认为它会变得丑陋。解析器听起来是一种更好的方法。谢谢
   01 Ams-Vendor.
       03 Brand               Pic x(3).
       03 Location-details.
          05 Location-Number  Pic 9(4).
          05 Location-Type    Pic XX.
          05 Location-Name    Pic X(35).
       03 Address-Details.
          05 actual-address.
             10 Address-1     Pic X(40).
             10 Address-2     Pic X(40).
             10 Address-3     Pic X(35).
          05 Postcode         Pic 9(4).
          05 Empty            pic x(6).
          05 State            Pic XXX.
       03 Location-Active     Pic X.
?xml version="1.0" encoding="UTF-8" standalone="no"?>
<copybook filename="cbl2xml_Test110.cbl">
    <item display-length="173" level="01" name="Ams-Vendor" position="1" storage-length="173">
        <item display-length="3" level="03" name="Brand" picture="x(3)" position="1" storage-length="3"/>
        <item display-length="41" level="03" name="Location-details" position="4" storage-length="41">
            <item display-length="4" level="05" name="Location-Number" numeric="true" picture="9(4)" position="4" storage-length="4"/>
            <item display-length="2" level="05" name="Location-Type" picture="XX" position="8" storage-length="2"/>
            <item display-length="35" level="05" name="Location-Name" picture="X(35)" position="10" storage-length="35"/>
        </item>
        <item display-length="128" level="03" name="Address-Details" position="45" storage-length="128">
            <item display-length="115" level="05" name="actual-address" position="45" storage-length="115">
                <item display-length="40" level="10" name="Address-1" picture="X(40)" position="45" storage-length="40"/>
                <item display-length="40" level="10" name="Address-2" picture="X(40)" position="85" storage-length="40"/>
                <item display-length="35" level="10" name="Address-3" picture="X(35)" position="125" storage-length="35"/>
            </item>
            <item display-length="4" level="05" name="Postcode" numeric="true" picture="9(4)" position="160" storage-length="4"/>
            <item display-length="6" level="05" name="Empty" picture="x(6)" position="164" storage-length="6"/>
            <item display-length="3" level="05" name="State" picture="XXX" position="170" storage-length="3"/>
        </item>
        <item display-length="1" level="03" name="Location-Active" picture="X" position="173" storage-length="1"/>
    </item>
</copybook>