[英]Python regular expression for repeating punctuation and symbols
我需要一個正則表達式來匹配重復(多個)標點和符號。 基本上所有重復的非字母數字和非空格字符,例如...,???,!!!,###,@@@,+++等。它必須是重復的同一字符,因此不能像“!?@”這樣的序列。
我嘗試過[^ \\ s \\ w] +,雖然涵蓋了所有!!!,???,$$的情況,但由於它也可以匹配“!?@”,因此它比我想要的更多。 。
有人可以啟發我嗎? 謝謝。
我認為您正在尋找這樣的東西:
[run for run, leadchar in re.findall(r'(([^\\w\\s])\\2+)', yourstring)]
例:
In : teststr = "4spaces then(*(@^#$&&&&(2((((99999****"
In : [run for run, leadchar in re.findall(r'(([^\w\s])\2+)',teststr)]
Out: ['&&&&', '((((', '****']
這為您提供了運行列表,不包括該字符串中的4個空格以及諸如'*(@ ^'
如果這不是您想要的,您可以使用示例字符串以及您想查看的輸出內容來編輯問題。
試試這個模式:
([.\?#@+,<>%~`!$^&\(\):;])\1+
\\1
指的是第一個匹配組,即括號的內容。
您需要根據需要擴展標點符號列表。
編輯:@Firoze Lafeer發布了一個答案,該答案使用單個正則表達式即可完成所有操作。 萬一有興趣將正則表達式與過濾功能結合使用的情況,我將不再贅述,但是對於此問題,使用Firoze Lafeer的答案將更加簡單快捷。
在我看到Firoze Lafeer的答案之前寫的答案沒有變化。
一個簡單的正則表達式不能做到這一點。 經典的精妙總結是“正則表達式無法計數”。 這里的討論:
對於Python解決方案,我建議將正則表達式與少量Python代碼結合使用。 正則表達式會拋出所有不包含某種標點符號的內容,然后Python代碼進行檢查以拋出錯誤的匹配項(包含標點符號但並非所有相同字符的匹配項)。
import re
import string
# Character class to match punctuation. The dash ('-') is special
# in character classes, so put a backslash in front of it to make
# it just a literal dash.
_char_class_punct = "[" + re.escape(string.punctuation) + "]"
# Pattern: a punctuation character followed by one or more punctuation characters.
# Thus, a run of two or more punctuation characters.
_pat_punct_run = re.compile(_char_class_punct + _char_class_punct + '+')
def all_same(seq, basis_case=True):
itr = iter(seq)
try:
first = next(itr)
except StopIteration:
return basis_case
return all(x == first for x in itr)
def find_all_punct_runs(text):
return [s for s in _pat_punct_run.findall(text) if all_same(s, False)]
# alternate version of find_all_punct_runs() using re.finditer()
def find_all_punct_runs(text):
return (s for s in (m.group(0) for m in _pat_punct_run.finditer(text)) if all_same(s, False))
我以這種方式編寫了all_same()
,以便它在迭代器上和在字符串上一樣好用。 Python內置的all()
對於空序列返回True
,這對於all_same()
特殊使用不是我們想要的,因此我為所需的基本情況設置了一個參數,並將其默認設置為True
以匹配行為在all()
。
這使用Python的內部組件(正則表達式引擎或all()
)完成了盡可能多的工作,因此它應該非常快。 對於大型輸入文本,您可能需要重寫find_all_punct_runs()
以使用re.finditer()
而不是re.findall()
。 我舉了一個例子。 該示例還返回生成器表達式而不是列表。 您可以隨時強制其列出:
lst = list(find_all_punct_runs(text))
這就是我要做的:
>>> st='non-whitespace characters such as ..., ???, !!!, ###, @@@, +++ and'
>>> reg=r'(([.?#@+])\2{2,})'
>>> print [m.group(0) for m in re.finditer(reg,st)]
要么
>>> print [g for g,l in re.findall(reg, st)]
任一打印:
['...', '???', '###', '@@@', '+++']
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.