Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can regular expressions find repetitions of characters?

Tags:

regex

My users insert sequences like

________________________
************************
------------------------
♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥

to format documents (dont ask me about my users!). And it looks bad when displaying snippets. How can I remove repetitions of any characters? I can add individual filters, but it will be a constant cat and mouse game.

Can a regular expression filter these?

like image 367
Jesvin Jose Avatar asked Oct 12 '11 06:10

Jesvin Jose


People also ask

What regex syntax is used for matching any number of repetitions *?

The asterisk or star tells the engine to attempt to match the preceding token zero or more times. The plus tells the engine to attempt to match the preceding token once or more. <[A-Za-z][A-Za-z0-9]*> matches an HTML tag without any attributes.

What are the three main uses of regular expressions?

The three basic operations in which regular expressions are used are: matching (Does this (entire) string match this pattern?) searching (Is this pattern found within this string?) transforming (such as replacing one or all occurrences of a pattern with another string)

Can regular expressions count?

Regular expressions can be used for a variety of text processing tasks, such as word-counting algorithms or validation of text inputs. In this tutorial, we'll take a look at how to use regular expressions to count the number of matches in some text.


3 Answers

Try something like:

(.)\1{5,}

Which matches any character, then 5 or more of that character. Remember to escape the \ if your language uses strings for regex patterns!

like image 124
Simon Buchan Avatar answered Oct 29 '22 23:10

Simon Buchan


You can remove repetitions of any character with a simple regex like (.)\1+

However, this will catch legitimate uses as well, such as words that have doubled letters in their spelling (balloon, spelling, well, etc).

So, you'd probably want to restrict the expression to some disallowed characters, after all, while keeping it as generic as possible, in order not to have to modify it from time to time, as your users find new characters to use.
One possible solution would be to disallow repeated non-letter and non-number characters:

([^A-Za-z0-9])\1+

But even this is not a definitive solution to all the cases, as some of your users may actually decide to use actual letter sequences as delimiters:

ZZZZZZZZZZZZZZZZZZZZZZ
BBBBBBBBBBBBBBBBBBBBBB
ZZZZZZZZZZZZZZZZZZZZZZ

In order not to allow this and with the added benefit of allowing legitimate uses of some repeated non-letter characters (such as in an ellipsis: ...), you could restrict the character repetitions to a maximum of 3, by using a regex with the syntax (<pattern>)\1{min, max} like this: (.)\1{4,} to match offending character sequences, with a minimum length of 4 and an unspecified maximum.

like image 25
luvieere Avatar answered Oct 29 '22 23:10

luvieere


In python (but the logic is the same regardless of the language):

>>> import re
>>> text = '''
... This is some text
... ________________________
... This some more
... ♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥
... Truly the last line
... '''
>>> print re.sub(r'[_♥]{2,}', '', text)  #this is the core (regexp)

This is some text

This some more

Truly the last line

This has the advantage that you have some control on what to substitute and what not (for example you might wish not to substitute . as it could be part of a comment like This is still to do....

EDIT:

If your repetitions are always "lines" you could add the newline characters to your expression:

text = '''
This is some text
________________________
This some more
♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥♥
Truly the last line
But this is not to be changed: ♥♥♥
'''
>>> print re.sub(r'\n[_♥]{2,}\n', '\n', text)
This is some text
This some more
Truly the last line
But this is not to be changed: ♥♥♥

HTH

like image 41
mac Avatar answered Oct 29 '22 23:10

mac