2010-06-30 41 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