2010-06-30 27 views
1

我試圖匹配後跟字母的「#」,當且僅當它的前面是換行符,空格或字符串中的第一個字符時。前兩個我已經完成了,但如果它是字符串中的第一個字符,我會很難匹配。我試圖找到'\ A'的用法,但它不能將它添加到包含換行符和空白符的類中。我錯過了什麼?嘗試匹配文本中的'#'

正則表達式我已經想出到目前爲止是:

from re import findall, escape 
from string import punctuation, whitespace 

NEWLINE = """\r\n?|\n""" 
INVALID_TAG_CHARACTERS = escape(punctuation.replace('-', '').replace('_', '') + whitespace) 
VALID_TAGS = r'[\s%s]+#[^%s]+' % (NEWLINE, INVALID_TAG_CHARACTERS) 
tags = findall(VALID_TAGS, text) 

回答

2

我認爲這是你在找什麼:

result = re.findall("(?:^|\s)(#[a-zA-Z]+)", text, re.MULTILINE) 

的:|是一組非分組括號(我們不希望這部分在我們的結果(^ \ s?) )。使用多行標誌,它將匹配字符串的開頭,或前面的換行符或空格。我相信下一組是你的'標籤'。如果它不是#之後的字母,那麼您將不得不擺弄第二組。

+0

這就像一個魅力,謝謝你! :-) 雖然我不得不將其更改爲「(?:^ | \ s)(#[^%s] +)%INVALID_TAG_CHARACTERS」。 – MdaG 2010-07-01 07:23:12

+0

@MdaG,你可能想使用're.escape(INVALID_TAG_CHARACTERS)'來確保你不會意外地在你的模式中注入正則表達式特殊字符。 – 2010-07-30 13:34:02

+0

是不是原來的帖子逃脫不夠? (即,' - ','')。替換('_','')+空格) – MdaG 2010-08-09 11:47:34

1

打開多行標誌,所以^一個換行符後的位置相匹配,那麼就使用:

re.compile(r"(?m)^\s*#") # includes the flag for multi-line 

或者

re.compile(r"(?m)^\s*#.*$") 

得到充分的線(禁用點匹配換行模式)。

對於「字符串中的第一個字符」,那要看是什麼字符串被定義爲 - 您可能需要使用一個完整的解析器對於這一點,而不是單一的正則表達式。

+0

啊錯過了「字符串位中的第一個字符」......已編輯過的答案包含了該信息,但不確定它是否非常有用。 :S – 2010-06-30 15:54:38

+0

'^'它不匹配換行符,它匹配*換行符和下一個字符(即多行模式)之間的假想間隔*。你可能已經知道了,但我不能讓這種說法不受挑戰。 – 2010-06-30 16:44:50

+0

好點,'^'和'$'匹配位置,不消耗實際字符是一個重要的區別。 – 2010-06-30 17:37:28