1

这是我第一次使用正则表达式进行模式匹配的经验,因此不胜感激。

我正在尝试在字符串中搜索以下子字符串:

"(TPU 1-999)
http://somewebaddress.com"

我想保留TPU,1-999和链接作为单独的子字符串。

这是我正在使用的模式:

^\s{3}\(([AEINPRSTUW]{3})\s(\d{1,3}.\d{2,5})\)$^\s{3}(http+\s{1,100})$

我会分解它来解释我的推理

^\s{3}- 字符串开头(或本例中的行),后跟 3 个空格

\(- 左括号

([AEINPRSTUW]{3})- 括号中任何字母的 3 个实例,TPU 是一个例子

\s(\d{1,3}.\d{2,5})- 一个空格,然后是 1-3 个数字,由 2-5 个数字中的任意字符分隔

\)$- 右括号,行尾

^\s{3}- 下一行的开头后跟三个空格

(http+\s{1,100})$- 字符“http”后跟 1 到 100 个非空白字符以及行尾。

这种模式现在不起作用,但我是否朝着正确的方向前进?

4

3 回答 3

4

$^这行不通。$是行尾(在换行之前),^是行的开头(在换行之后)。但是换行符是一个字符(或两个),同时不推进正则表达式引擎的位置。因此$,并^尝试匹配相同的位置,这只有在它们是空行的结尾和开头时才会发生 - 即使这样将它们按此顺序排列也会产生很大的误导。如果您想确保它们之间恰好有一个换行符,请尝试以下操作:

^\s{3}\(([AEINPRSTUW]{3})\s(\d{1,3}.\d{2,5})\)$(\r\n?|\n)^\s{3}(http+\S{1,100})$

但是,正如 ridgerunner 指出的评论,以下\s{3}可以匹配(最多 3 个)更多的换行符,因为它们也是空格。

另请注意,.作为数字的分隔符可能不是最好的主意。至少,使用非数字字符:

^\s{3}\(([AEINPRSTUW]{3})\s(\d{1,3}\D\d{2,5})\)$(\r\n?|\n)^\s{3}(http+\S{1,100})$

另请注意,我已将您的最后一个更改\s\S(因为\s是空格,\S是非空格)。

另请注意,您向我们展示的字符串不包含您尝试匹配的那三个空格。因此,将它们设为可选(正如 CaptainMurphy 建议的那样)也可能会有所帮助:

^\s*\(([AEINPRSTUW]{3})\s(\d{1,3}\D\d{2,5})\)$(\r\n?|\n)^\s*(http+\S{1,100})$

由于我们已经匹配了换行符,我们也可以完全删除那里的锚点,它们不再有帮助:

^\s*\(([AEINPRSTUW]{3})\s(\d{1,3}\D\d{2,5})\)(\r\n?|\n)\s*(http+\S{1,100})$
于 2012-10-25T15:44:56.870 回答
1

我认为您对大写字母和特定数量的空格等内容过于具体(您的示例字符串开头甚至没有空格)。我大多只是坚持 * 和 + 除非我正在寻找非常具体的东西。正如另一个答案指出的那样, $ 是整个记录(字符串)的结尾,而不是行尾。换行符或 CRLF 只是空格。不要将 \s 甚至 [^\s] 用于非空白,使用 \S。

ss="(TPU 1-999)\nhttp://something.com"
rr="^\s*\(([A-Z]+)\s+(\d+.\d+)\)\s+(http\S{1,100})$"
re.match(rr,ss).groups()
('TPU', '1-999', 'http://something.com')
于 2012-10-25T15:49:02.760 回答
1

这个我真的是想多了。这是我根据提供的答案提出的解决方案:

这是我正在解析的字符串的示例(从电子邮件的内容中提取):

'The writeboard named "10/26 newsletters (Pat)" has been created:\r\n\r\n (TPU 1000+)\r\n\r\n http://www.techproductupdate.com/resources/2313/splunk-app-for-vmware-delivers-insight-into-the-cloud\r\n\r\n (TIN 250+)\r\n\r\n http://www.techproductupdate.com/resources/2369/securing-mysql-databases\r\n\r\n (TPU 500+)\r\n\r\n http://www.techproductupdate.com/resources/2333/designing-a-data-protection-strategy-with-hp-lefthand-hp-storeonce-and-hp-tape\r\n\r\n- - -\r\nYou can visit the writeboard at:\r\n http://somewebsite.com\r\n'

所以首先我只是使用re.findall模式来定位括号之间的所有内容'\((?P<list>[A-Z]*)\s(?P<segments>.+)\)'

然后我使用re.findall该模式定位所有 URL - 这将返回我想要的所有结果以及列表末尾的'http\S*'额外结果。'http://somewebsite.com'

然后我只是将这些列表压缩在一起,不包括最后一个列表的最后一个元素,我基本上得到了我首先要寻找的结果。

于 2012-10-25T18:11:27.470 回答