Python 正则表达式中的可选括号

Python 正则表达式中的可选括号,python,regex,Python,Regex,在python中使用以下字符串 1 - GENERAL 1 1.1 RELATED DOCUMENTS 1 1.2 SUMMARY 1 1.3 DEFINITIONS 1 1.4 INFORMATIONAL SUBMITTALS 2 1.5 GENERAL COORDINATION PROCEDURES 2 1.6 COORDINATION DRAWINGS 3 1.7 REQUESTS FOR INFORMAT

在python中使用以下字符串

1 - GENERAL 1

    1.1 RELATED DOCUMENTS   1

    1.2 SUMMARY 1

    1.3 DEFINITIONS 1

    1.4 INFORMATIONAL SUBMITTALS    2

    1.5 GENERAL COORDINATION PROCEDURES 2

    1.6 COORDINATION DRAWINGS   3

    1.7 REQUESTS FOR INFORMATION (RFIs) 4

    1.8 PROJECT MEETINGS    6
我试图创建一个regit表达式,将节、标题和页码分为3组。到目前为止我有

 (\d)(\.|\d|\s|-)+\s+([^a-z]+?)\s+\d
它可以处理除(RFI)之外的所有情况。我怎么也能抓住这个? 注意:有时字符串可能包含我不想要的小写小节。这就是[^a-z]出现的原因。此外,RFI可能并不总是括号中的文本

更新:

END OF SECTION



    Project No. 151219.00   012500 - 1 of 3 Substitution Procedures

            Rev. 0, 07/23/15

            Issued for Construction

字符串中主要包含三个部分

首先是段,主要由数字、小数和数字组成

第二个是页码以内的任何内容。这主要是从单词开始的

第三是最后一页的页码,通常是数字

您的正则表达式包含太多不需要的替换项。 所以你可以用这个正则表达式

^\s*(\b\d+(?:[.]\d+)?)\W+(.*?)\s*(\b\d+\b)$
    <---------------->   <--->   <------->
        Section         Content  Page Number
正则表达式分解

\b

\W
相当于
[^\W]
,后者又是
[^A-Za-z0-9\]
(注意
^
,表示除字符类中的匹配项外的任何匹配项)


我推荐这样的东西

    ^\s*([\d.]+)[\s-]*\s+(.+?)\s+(\d+)$
既然您说您使用的是python,那么当涉及到诸如注释之类的内容时,这就为您提供了更多的功能。例如:

    ^\s*(?#Section)([\d.]+)[\s-]*\s+(?#Title)(.+?)\s+(?#Page)(\d+)$
Regex功能非常强大,但如果您是新手或刚刚脱离实践,则通常无法阅读。在这种情况下,评论是天赐之物

完整的实现如下所示:

    re.search(r'^\s*(?#Section)([\d.]+)[\s-]*\s+(?#Title)(.+?)\s+(?#Page)(\d+)$', input_string, re.M)

其中re.M表示它应该在多行模式下运行,使^匹配每行的开头,而不是整个输入的开头。$和行尾/输入相同

显示一些使其变得复杂的其他字符串的示例(小节、RFI等)。看起来更简单的“数字,后面跟任何东西,后面跟一个数字”是您真正需要的。
^\s*[1-9\.]*\s*[a-Z^a-Z\-\s]+[a-Z^a-Z\-]\s*[0-9]*
为什么更好?一个小小的解释会让这个答案变得更好。太棒了,真管用!不过,我对regex还是新手。今天早上刚开始学习,这让我很困惑,\b\d+(?:[.]\d+*)\W+。你能解释一下这里发生了什么事吗?谢谢,我还有一个问题要问你。我正在分析的一个文档包含我在update下发布的字符串,您提供的表达式提取了这条不需要的信息。如何编辑您提供的表达式以忽略这些内容?Thanks@Jstuff我不认为这是在挑拣什么你能检查一下我是不是执行错了什么吗。当我执行text=(re'^\s*(\b\d+(?:[.]\d+)\W+(.*?)\s*(\b\d+\b)$)时,输入\u strong,re.M)它不会返回任何匹配项。当我执行text=(re.findall(r'\s*(\b\d+(?:[.]\d+))\W+(.*?)\s*(.*)\b\d+\b)时,输入字符串)它在我发布的文本框中查找匹配项,再加上第二个文本框中我不想要的匹配项。为什么第一个方法不返回任何匹配项?使用re.search和re.M标志和^,&或re.findall并省略标志和^,&?我想这种方法也可以工作,尽管这种方法将返回带有3个匹配。每次匹配传递的数据集越大,难以追踪的edgecase最终将数据移动一个点或某个点的可能性就越大
    ^\s*(?#Section)([\d.]+)[\s-]*\s+(?#Title)(.+?)\s+(?#Page)(\d+)$
    re.search(r'^\s*(?#Section)([\d.]+)[\s-]*\s+(?#Title)(.+?)\s+(?#Page)(\d+)$', input_string, re.M)