[英]Python regular expression for repeating punctuation and symbols
I need a regex that will match repeating (more than one) punctuation and symbols. 我需要一个正则表达式来匹配重复(多个)标点和符号。 Basically all repeating non-alphanumeric and non-whitespace characters such as ..., ???, !!!, ###, @@@, +++ and etc. It must be the same character that's repeated, so not a sequence like "!?@".
基本上所有重复的非字母数字和非空格字符,例如...,???,!!!,###,@@@,+++等。它必须是重复的同一字符,因此不能像“!?@”这样的序列。
I had tried [^\\s\\w]+ and while that covers all off the !!!, ???, $$$ cases, but that gives me more than what I want since it will also match "!?@". 我尝试过[^ \\ s \\ w] +,虽然涵盖了所有!!!,???,$$的情况,但由于它也可以匹配“!?@”,因此它比我想要的更多。 。
Can someone enlighten me please? 有人可以启发我吗? Thanks.
谢谢。
I think you're looking for something like this: 我认为您正在寻找这样的东西:
[run for run, leadchar in re.findall(r'(([^\\w\\s])\\2+)', yourstring)]
Example: 例:
In : teststr = "4spaces then(*(@^#$&&&&(2((((99999****"
In : [run for run, leadchar in re.findall(r'(([^\w\s])\2+)',teststr)]
Out: ['&&&&', '((((', '****']
This gives you a list of the runs, excluding the 4 spaces in that string as well as sequences like '*(@^' 这为您提供了运行列表,不包括该字符串中的4个空格以及诸如'*(@ ^'
If that's not exactly what you want, you might edit your question with an example string and precisely what output you wanted to see. 如果这不是您想要的,您可以使用示例字符串以及您想查看的输出内容来编辑问题。
Try this pattern: 试试这个模式:
([.\?#@+,<>%~`!$^&\(\):;])\1+
\\1
is referring to the first matched group, which is contents of the parentheses. \\1
指的是第一个匹配组,即括号的内容。
You need to extend the list of punctuations and symbols as desired. 您需要根据需要扩展标点符号列表。
EDIT: @Firoze Lafeer posted an answer that does everything with a single regular expression. 编辑:@Firoze Lafeer发布了一个答案,该答案使用单个正则表达式即可完成所有操作。 I'll leave this up in case anyone is interested in combining a regular expression with a filtering function, but for this problem it would be simpler and faster to use Firoze Lafeer's answer.
万一有兴趣将正则表达式与过滤功能结合使用的情况,我将不再赘述,但是对于此问题,使用Firoze Lafeer的答案将更加简单快捷。
Answer written before I saw Firoze Lafeer's answer is below, unchanged. 在我看到Firoze Lafeer的答案之前写的答案没有变化。
A simple regular expression can't do this. 一个简单的正则表达式不能做到这一点。 The classic pithy summary is "regular expressions can't count".
经典的精妙总结是“正则表达式无法计数”。 Discussion here:
这里的讨论:
How to check that a string is a palindrome using regular expressions? 如何使用正则表达式检查字符串是回文?
For a Python solution I would recommend combining a regular expression with a little bit of Python code. 对于Python解决方案,我建议将正则表达式与少量Python代码结合使用。 The regular expression throws out everything that isn't a run of some sort of punctuation, and then the Python code checks to throw out false matches (matches that are runs of punctuation but not all the same character).
正则表达式会抛出所有不包含某种标点符号的内容,然后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))
I wrote all_same()
the way I did so that it will work just as well on an iterator as on a string. 我以这种方式编写了
all_same()
,以便它在迭代器上和在字符串上一样好用。 The Python built-in all()
returns True
for an empty sequence, which is not what we want for this particular use of all_same()
, so I made an argument for the basis case desired and made it default to True
to match the behavior of all()
. Python内置的
all()
对于空序列返回True
,这对于all_same()
特殊使用不是我们想要的,因此我为所需的基本情况设置了一个参数,并将其默认设置为True
以匹配行为在all()
。
This does as much of the work as possible using the internals of Python (the regular expression engine or all()
) so it should be pretty fast. 这使用Python的内部组件(正则表达式引擎或
all()
)完成了尽可能多的工作,因此它应该非常快。 For large input texts you might want to rewrite find_all_punct_runs()
to use re.finditer()
instead of re.findall()
. 对于大型输入文本,您可能需要重写
find_all_punct_runs()
以使用re.finditer()
而不是re.findall()
。 I gave an example. 我举了一个例子。 The example also returns a generator expression rather than a list.
该示例还返回生成器表达式而不是列表。 You can always force it to make a list:
您可以随时强制其列出:
lst = list(find_all_punct_runs(text))
This is how I would do it: 这就是我要做的:
>>> st='non-whitespace characters such as ..., ???, !!!, ###, @@@, +++ and'
>>> reg=r'(([.?#@+])\2{2,})'
>>> print [m.group(0) for m in re.finditer(reg,st)]
or 要么
>>> print [g for g,l in re.findall(reg, st)]
Either one prints: 任一打印:
['...', '???', '###', '@@@', '+++']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.