<p>如果你需要一个复杂的正则表达式,一步一步地构建它是很重要的。那是避免迷路的唯一方法。你知道吗</p>
<p>开始前注意两个问题:</p>
<ul>
<li><p>我不熟悉法律术语。我的术语可能全错了。</p></li>
<li><p>我将使用<a href="https://docs.python.org/2/library/re.html#re.X" rel="nofollow">verbose flag</a>。有了这个标志,您可以在正则表达式中自由地插入空格,以提高可读性。</p></li>
</ul>
<p>让我们从法规号开始,定义一个解析单个组件的正则表达式(例如<code>34A</code>或<code>83.1</code>)。你知道吗</p>
<pre><code>nbr = r'\d+ (?: \. \d+ )? [A-Z]?'
</code></pre>
<p>其中三到五个组成部分,用破折号隔开,构成一个完整的法规编号。你知道吗</p>
<pre><code>statute = r'%(nbr)s (?: - %(nbr)s ){2,4}' % {
'nbr': nbr
}
</code></pre>
<p>有了这个,我们就可以定义一个既匹配一个规约又匹配一个范围的正则表达式。我们用两个小组来收集法规。第二个将是空的,因为没有给出范围。你知道吗</p>
<pre><code>statute_or_range = r'(%(statute)s) (?: \s+ to \s+ (%(statute)s) )?' % {
'statute': statute
}
</code></pre>
<p>现在我们可以构造一个模式来匹配整个第一行。在这一点上,很容易处理有时出现的逗号。你知道吗</p>
<pre><code>action = r'(?:Superseded|Repealed|Transferred|Obsolete|Reserved|Rejected|Omitted|Not|Executed)'
first_line = r'%(statute_or_range)s ,? \s+ %(action)s \. \s+' %{
'statute_or_range': statute_or_range,
'action': action
}
</code></pre>
<p>我不太清楚你要匹配多少文本。我的印象是,你想捕捉到下一个法令的开头,这是一个以法令编号开始的行。所以:</p>
<pre><code>end = r'(?= \n %(statute)s )' % {
'statute': statute
}
</code></pre>
<p>将这些组合起来,就可以得到正则表达式:</p>
<pre><code>pattern = r'%(first_line)s (.*?) %(end)s' % {
'first_line': first_line,
'end': end
}
regex = re.compile(pattern, re.VERBOSE | re.DOTALL | re.IGNORECASE)
</code></pre>
<p><a href="http://regex101.com/r/vX7cI4/2" rel="nofollow">See it in action.</a></p>