The PCRE-compatible regex to match this would be:

/([\s.',-])\1+/

If you're using Perl, you can replace it using the following expression:

s/([\s.',-])\1+/$1/g

If you're using PHP, then you would use this syntax:

$out = preg_replace('/([\s.\',-])\1+/', '$1', $in);

Explanation

  • The () group matches the single character, in this case either a whitespace character (\s) or the punctuation characters (. ' - ,). It's good practice to put - at the end of the list inside [].
  • The \1 means that the same thing it just matched in the parentheses occurs at least once more.
  • In the replacement, the $1 refers to the match in first set of parentheses.

Note: this is Perl-Compatible Regular Expression (PCRE) syntax.

From the perlretut man page:

Matching repetitions

The examples in the previous section display an annoying weakness. We were only matching 3-letter words, or chunks of words of 4 letters or less. We'd like to be able to match words or, more generally, strings of any length, without writing out tedious alternatives like \w\w\w\w|\w\w\w|\w\w|\w.

This is exactly the problem the quantifier metacharacters ?, *, +, and {} were created for. They allow us to delimit the number of repeats for a portion of a regexp we consider to be a match. Quantifiers are put immediately after the character, character class, or grouping that we want to specify. They have the following meanings:

  • a? means: match 'a' 1 or 0 times

  • a* means: match 'a' 0 or more times, i.e., any number of times

  • a+ means: match 'a' 1 or more times, i.e., at least once

  • a{n,m} means: match at least "n" times, but not more than "m" times.

  • a{n,} means: match at least "n" or more times

  • a{n} means: match exactly "n" times

Answer from amphetamachine on Stack Overflow
Top answer
1 of 4
18

The PCRE-compatible regex to match this would be:

/([\s.',-])\1+/

If you're using Perl, you can replace it using the following expression:

s/([\s.',-])\1+/$1/g

If you're using PHP, then you would use this syntax:

$out = preg_replace('/([\s.\',-])\1+/', '$1', $in);

Explanation

  • The () group matches the single character, in this case either a whitespace character (\s) or the punctuation characters (. ' - ,). It's good practice to put - at the end of the list inside [].
  • The \1 means that the same thing it just matched in the parentheses occurs at least once more.
  • In the replacement, the $1 refers to the match in first set of parentheses.

Note: this is Perl-Compatible Regular Expression (PCRE) syntax.

From the perlretut man page:

Matching repetitions

The examples in the previous section display an annoying weakness. We were only matching 3-letter words, or chunks of words of 4 letters or less. We'd like to be able to match words or, more generally, strings of any length, without writing out tedious alternatives like \w\w\w\w|\w\w\w|\w\w|\w.

This is exactly the problem the quantifier metacharacters ?, *, +, and {} were created for. They allow us to delimit the number of repeats for a portion of a regexp we consider to be a match. Quantifiers are put immediately after the character, character class, or grouping that we want to specify. They have the following meanings:

  • a? means: match 'a' 1 or 0 times

  • a* means: match 'a' 0 or more times, i.e., any number of times

  • a+ means: match 'a' 1 or more times, i.e., at least once

  • a{n,m} means: match at least "n" times, but not more than "m" times.

  • a{n,} means: match at least "n" or more times

  • a{n} means: match exactly "n" times

2 of 4
1

As others said it depends on you regex engine but a small example how you could do this: /([ _-,.])\1*/\1/g

With sed:

$ echo "foo    , bar" | sed 's/\([ _-,.]\)\1*/\1/g'
foo , bar
$ echo "foo,. bar" | sed 's/\([ _-,.]\)\1*/\1/g'
foo,. bar
Discussions

java - Regex to replace repeated characters - Stack Overflow
Can someone give me a Java regex to replace the following. If I have a word like this "Cooooool", I need to convert this to "Coool" with 3 o's. So that I can distinguish it with the normal word "c... More on stackoverflow.com
🌐 stackoverflow.com
August 18, 2015
How to replace any number of repeating characters in a string or character array
How to replace any number of repeating... Learn more about regex, strrep Text Analytics Toolbox More on mathworks.com
🌐 mathworks.com
2
0
May 31, 2020
Regex to match repeating characters
I’ve found that this regular expression R is used to match repeating characters in a string · I can’t see how it does this? When I omit the \1+, so that the expression becomes var R = /[^]/g It matches every individual character in a string. I understand that the caret ^ in square brackets ... More on forum.freecodecamp.org
🌐 forum.freecodecamp.org
1
0
April 27, 2022
java - Replace multiple occurrences of a character - Code Review Stack Exchange
I try to replace multiple occurrences of a character with a single character. Input: hhiii!!! hooowww aaareee yyyooou??? Output: hi! how are you? public class CharSingleOccurrence { p... More on codereview.stackexchange.com
🌐 codereview.stackexchange.com
November 27, 2011
🌐
Analytics Vidhya
discuss.analyticsvidhya.com › t › need-help-with-removing-duplicate-characters-with-regex › 80518
Data Science and Artificial Intelligence | Analytics Vidhya
August 5, 2019 - Unlock Your Data Science Potential with Analytics Vidhya's Community Hub. Join passionate data science enthusiasts, collaborate, and stay updated on the latest trends. Access expert resources, engage in insightful discussions, and accelerate your career in data science, machine learning, and AI
🌐
David Walsh
davidwalsh.name › replace-repeated-characters
Replace Repeated Characters with JavaScript
August 10, 2018 - const prettyPath = urlObj.path....org/fbjs/0.8.17/node_modules/fbjs/lib/isNode.js · The {2,} part of the regular expression only allows for one of the repeated characters, and /g ensures that multiple instances within the string ...
🌐
MathWorks
mathworks.com › matlabcentral › answers › 538679-how-to-replace-any-number-of-repeating-characters-in-a-string-or-character-array
How to replace any number of repeating characters in a string or character array - MATLAB Answers - MATLAB Central
May 31, 2020 - https://www.mathworks.com/matlabcentral/answers/538679-how-to-replace-any-number-of-repeating-characters-in-a-string-or-character-array#answer_443367 · Cancel Copy to Clipboard · Something like this · str = fileread('test.txt'); new_str = regexprep(str, ':\.{2,}', ',') Result ·
🌐
freeCodeCamp
forum.freecodecamp.org › programming › javascript
Regex to match repeating characters - JavaScript
April 27, 2022 - var R = /([^])\1+/g I’ve found that this regular expression R is used to match repeating characters in a string. e.g “HazzzeLLllnut$$$”.match(R) returns [“zzz”,“LL”,“ll”,"$$$"] I can’t see how it does this? When I omi…
Find elsewhere
🌐
GeeksforGeeks
geeksforgeeks.org › python-replace-multiple-occurrence-of-character-by-single
Python | Replace multiple occurrence of character by single - GeeksforGeeks
July 31, 2023 - If repeated multiple times, append the character single time to the list. Other characters(Not the given character) are simply appended to the list without any alteration. ... # Python program to replace multiple # occurrences of a character ...
🌐
YouTube
youtube.com › watch
Regular Expressions (RegEx) Tutorial #5 - Repeating Characters - YouTube
Hey all, in this RegEx tutorial I'll show you how wecan easily repeat characters in a pattern, rather than write tem all out by hand.DONATE :) - https://www....
Published   February 18, 2018
🌐
Regular-Expressions.info
regular-expressions.info › repeat.html
Regex Tutorial: Repetition with Star and Plus
The star will cause the second character class to be repeated three times, matching T, M and L with each step. <[A-Za-z0-9]+> also matches valid HTML tags. But it also matches things like <1> that are not valid HTML tag. But this regex may be sufficient if you know the string you are searching through does not contain any such invalid tags.
Top answer
1 of 3
11

I think this is oddly complicated...though, I'm 99% sure this can be done with a single line of RegEx, I don't know how from the top of my head1.

This can be shortened to a much simpler and shorter solution, without the need of arrays at all.

String input = "hhiii!!!  hooowww   aaareee   yyyooou???";
StringBuilder output = new StringBuilder();

// Append the first character of the string.
// We can also let the loop start at 0, but then
// we'd need an additional if inside the loop, which
// I'd like to avoid.
output.append(input.charAt(0));

// Start the loop at 1, because we already have the first character.
// We can not 
for (int idx = 1; idx < input.length(); idx++) {
    // Check the current against the previous character.
    if(input.charAt(idx) != input.charAt(idx-1)) {
        // If it is not the same, append it.
        output.append(input.charAt(idx));
    }
 }

Of course you'd need to protect yourself from invalid input (empty or null String), and it will also break words with allowed double-characters: foobar, tool, support etc..

Some further comments on your code:

  • Function name: It's not directly visible what the function does. It should be called something along the lines of removeDoubleChars or removeMultipleCharacters.
  • Function type: The function shouldn't directly output the result to System.out but rather return it.
  • Loops: Use appropriate loops, f.e. your while should be a for.
  • Variable names: I know it's partly taught, but I get the creeps (or become a Creeper) if I see variables which are named i, j or arr. Give your variables meaningful names! In any modern language the name of the variable is neither limited nor does it matter for performance. Write your code primarily for humans, and only secondary for machines...the coder which has to maintain your code after you will thank you.
  • Whitespaces: Use 'em! if(str.charAt(i)!=str.charAt(i+1)){ is harder to read then if(str.charAt(i) != str.charAt(i + 1)) {.
  • Code duplication: Avoid duplicate code. In this case it's minor, but the i++ should be moved outside the if, so that it's not necessary to have an else part.

1: But John does.

2 of 3
11

Maybe I am wrong but I prefers to use the regex for this kind of text manipulation. Here is my code,

System.out.println("hhiii!!!  hooowww   aaareee   yyyooou???"
                      .replaceAll("(.)\\1+","$1"));
🌐
Reddit
reddit.com › r/regex › wanting to replace any instance of multiple 'characters' with a single character.
r/regex on Reddit: Wanting to replace any instance of multiple 'characters' with a single character.
December 16, 2021 -

I have a situation where there are multiple periods from string (i.e. Hello.......)

I am attempting to create a REPLACE to look for any instance where there are multiple periods, and replace with just one.

'Hello.......' would be 'Hello.'

text = 'Hello.......'
text = Regex.Replace(text, ".{2,}", ".")

But this doesnt seem to work..

Any assistance is appreciated.

🌐
Medium
nick3499.medium.com › javascript-using-regex-pattern-match-to-remove-repeated-character-from-end-of-string-replace-47870bd095de
JavaScript: Using Regex Pattern Match to Remove Repeated Character from End of String: replace(), regex | by nick3499 | Medium
June 14, 2018 - $ sudo node > const remove = s => s.replace(/!+$/, "") > console.log(remove("Hi!!!!!")) Hi · Regular expressions, aka regex patterns, can become cryptically exasperating, since they can be riddled with specialized characters. Or overwhelming, depending upon how large they become.
Top answer
1 of 4
1
  • Ctrl+H
  • Find what: ^(\w+,\h*)(\w+)(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?(?:,\h*(\w+))?
  • Replace with: $1$2\n(?3$1$3)(?4\n$1$4)(?5\n$1$5)(?6\n$1$6)(?7\n$1$7)(?8\n$1$8)(?9\n$1$9)
  • TICK Match case
  • TICK Wrap around
  • SELECT Regular expression
  • UNTICK . matches newline
  • Replace all

Explanation:

^               # beginning of line
    (               # group 1
        \w+             # 1 or more word characters
        ,               # a comma
        \h*             # 0 or more horizontal spaces
    )               # end group 1
    (\w+)           # group 2, 1 or more word characters
    (?:             # non capture group
        \h*             # 0 or more horizontal spaces
        (\w+)           # group 3, 1 or more word characters
    )?              # end group, optional
(?:,\h*(\w+))?      # same as above
(?:,\h*(\w+))?      # same as above
(?:,\h*(\w+))?      # same as above
(?:,\h*(\w+))?      # ... 
(?:,\h*(\w+))?      # ... 
(?:,\h*(\w+))?      # ... 
(?:,\h*(\w+))?      # ... 
(?:,\h*(\w+))?      # ... 

Replacement:

$1              # content of group 1
$2              # content of group 2
\n              # line feed, you can use \r\n for Windows
(?3             # if group 3 exists
    $1              # content of group 1
    $3              # content of group 3
)               # endif
(?4\n$1$4)      # same as above
(?5\n$1$5)      # ...
(?6\n$1$6)      # ...
(?7\n$1$7)      # ...
(?8\n$1$8)      # ...
(?9\n$1$9)      # ...

Screenshot (before):

Screenshot (after):

2 of 4
2

That regex is way too complicated. By using an actual programming language, things will be much simpler.

Here I give an example in Python. Get Python here.

Say you have this input:

Chicago, ORD, MDW
NY, JFK, LGA, EWR
California, LAX, JWA, LGB, BUR

And you want to convert it to your given output:

Chicago, ORD
Chicago, MDW  
NY, JFK
NY, LGA
NY, EWR
California, LAX
California, JWA
California, LGB
California, BUR

It is simple, first split the string into lines, the split each line into list of strings by commas. Finally return the combination of the first element and every other element of the same list.

lines = """Chicago, ORD, MDW
NY, JFK, LGA, EWR
California, LAX, JWA, LGB, BUR"""

for line in lines.splitlines():
    lst = line.split(', ')
    first = lst[0]
    for e in lst[1:]:
        print(f'{first}, {e}')
🌐
RegexOne
regexone.com › lesson › repeating_characters
RegexOne - Learn Regular Expressions - Lesson 6: Catching some zzz's
We've so far learned how to specify the range of characters we want to match, but how about the number of repetitions of characters that we want to match? One way that we can do this is to explicitly spell out exactly how many characters we want, eg.
🌐
Randomdrake
randomdrake.com › 2008 › 04 › 10 › php-and-regex-replacing-repeating-characters-with-single-characters-in-a-string
PHP and Regex – Replacing Repeating Characters with Single Characters in a String | Random Drake
April 10, 2008 - So, when it comes to the first character repeating more than once, it will replace it with a single version of itself (or $1). It then places itself back in at the location of the backslash-1 {(.)\1+}. Throughout the night until the wee hours of the morning I was furthering my ‘regex-fu’. I ultimately came to a simple loop that seems to satisfy the issue.