Python正则表达式中可变宽度lookbehind的替代方案

时间:2015-07-22 13:12:13

标签: python regex lookaround

我最近决定跳进Python池的深层,开始将我的一些R代码转换为Python,而且我遇到了对我来说非常重要的事情。在我的工作中,我花了很多时间来解析文本数据,正如我们所知,这些数据非常非结构化。因此,我开始依赖正则表达式的外观特性,而R的外观功能非常强大。例如,如果我在解析文件时解析可能在字母之间引入一些空格的PDF,我会得到我想要的值,如下所示:

oAcctNum <- str_extract(textBlock[indexVal], "(?<=ORIG\\s?:\\s?/\\s?)[A-Z0-9]+")

在Python中,这是不可能的,因为使用?使得lookbehind成为可变宽度表达式而不是固定宽度。这个功能对我来说非常重要,它阻止我想要使用Python,但是我不想放弃语言,而是想知道Pythonista解决这个问题的方法。在提取文本之前,我是否必须预处理字符串?像这样:

oAcctNum = re.sub(r"(?<=\b\w)\s(?=\w\b)", "")
oAcctNum = re.search(r"(?<=ORIG:/)([A-Z0-9])", textBlock[indexVal]).group(1)

有更有效的方法吗?因为虽然这个例子很简单,但是这个问题在我使用的数据中以非常复杂的方式出现,我不想为我分析的每一行文本做这种预处理。

最后,如果这不是提出这个问题的正确位置,我会道歉;我不确定在哪里发布它。提前谢谢。

3 个答案:

答案 0 :(得分:2)

在您描述的情况下,您需要使用capture groups

"(?<=ORIG\\s?:\\s?/\\s?)[A-Z0-9]+"

将成为

r"ORIG\s?:\s?/\s?([A-Z0-9]+)"

该值将在.group(1)中。请注意,原始字符串是首选。

以下是示例代码:

import re
p = re.compile(r'ORIG\s?:\s?/\s?([A-Z0-9]+)', re.IGNORECASE)
test_str = "ORIG:/texthere"
print re.search(p, test_str).group(1)

IDEONE demo

除非您需要重叠匹配,否则捕获组使用而不是后视是相当简单的。

答案 1 :(得分:2)

请注意,如果您可以使用群组,则通常不需要外观。那怎么样呢?

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select type='list' name='sensors' multiple>
  <option value= "e11">e11</option>
  <option value= "e12">e12</option>
  <option value= "e13">e13</option>
  <option value= "e14">e14</option>
</select>
<!--jQuery onclick()-->
<div id="demo"></div>
<!--jQuery select()-->
<div id="demo2"></div>

在实践中:

match = re.search(r"ORIG\s?:\s?/\s?([A-Z0-9]+)", string)
if match:
    text = match.group(1)

答案 2 :(得分:0)

print re.findall(r"ORIG\s?:\s?/\s?([A-Z0-9]+)",test_str)

您可以直接使用findall,这将返回正则表达式中的所有组(如果存在)。