1

I have a string: aaa, bbb, ccc, ddd Result I need: aaa aaa_, bbb bbb_, ccc ccc_, ddd ddd_

I tried this way: "aaa, bbb, ccc, ddd".replaceAll("(.*?)((, )|$)", "$1 $1_,")

Result with this pattern: aaa aaa_, bbb bbb_, ccc ccc_, ddd ddd_, _,

I don't want to see , _, at the and of return.

Any suggestions please how can I do it in Java?

0

4 Answers 4

4

Try this.

String r = "aaa, bbb, ccc, ddd".replaceAll("\\w+", "$0 $0_");
System.out.println(r);

result:

aaa aaa_, bbb bbb_, ccc ccc_, ddd ddd_
Sign up to request clarification or add additional context in comments.

3 Comments

This perfectly Ok! How does back reference $0 works in pattern without capturing group? 0 is some kind of implicit group?
$0 (Group zero) always stands for the entire expression.
Thanks a lot @saka1029 and everyone who gave answers!
2

Change the quantifier and I think you'll be good to go. The * is zero or more occurrences.

Are there always three pairings? Maybe something like

(.{3,})((, )|$)

or

([a-z]{3,})((, )|$)

would be better.

The + can be used in place of {3} if there should just be one or more. If there should be exactly three remove the trailing comma. The {} creates a range and with a , it sets a min and a max.

You can change the substitution pattern to:

$1 $1_$2

to get rid of the trailing comma but you'll need to do some right trim to remove the last underscore (in PHP it would be rtrim).

Comments

0

You may try:

(\w+)

Explanation of the above regex:

( - Represents the start of the capturing group

\w - Represents a word character matching from [0-9a-zA-Z_]. If you don't want to include _ then you can provide it manually; something like [0-9A-Za-z]+.

+ - Represents quantifier matching the word characters 1 or more times.

) - Represents the end of the capturing group.

$1 $1_ - For the replacement part you may use the captured group space and captured group along with an _

You can find the demo of the above regex in here.


import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class Main
{
    private static final Pattern pattern = Pattern.compile("(\\w+)");
    public static void main(String[] args) {
        String string = "aaa, bbb, ccc, ddd\n"
     + "some, someone, something, hello";
        
        String subst = "$1 $1_";
        
        Matcher matcher = pattern.matcher(string);
        
        String result = matcher.replaceAll(subst);
        System.out.println(result);
    }
}

You can find the sample run of the above implementation in here.

Comments

0

tl;dr

Skip the regex. Just use string manipulation, in a single statement.

Arrays
        .stream( "aaa, bbb, ccc, ddd".split( ", " ) )  // Parse the text using COMMA with SPACE as the delimiter. 
        .map( ( String s ) -> s + " " + s + "_" )      // Change `aaa` to `aaa aaa_`. 
        .collect( Collectors.joining( ", " ) );        // Join the modified strings together as a single string.

aaa aaa_, bbb bbb_, ccc ccc_, ddd ddd_


String::split

No need for regex.

You can accomplish this goal by splitting the comma-separated words into an array of strings, make a stream of that array, and join them back together again with no extra terminator. And, you can do all than in a one-liner.

Given this input:

String input = "aaa, bbb, ccc, ddd";

…split the string into pieces.

String[] pieces =  input.split( ", " ) ;

Stream

Make a stream of those pieces.

Stream < String > streamOfPieces = Arrays.stream( pieces ) ;

Take each element from the stream and transform each by adding a SPACE, the same string again, and the underscore you want at the end.

Stream < String > streamOfModifiedPieces = streamOfPieces.map( ( String s ) -> s + " " + s + "_" );

Collect results of stream

Terminate the stream by collecting all those transformed elements with a Collector. The Collector implementation we need is provided by a call to Collectors.joining. We pass our desired delimiter to that collector. In our case, the desired delimiter is a COMMA and a SPACE, ,. The collector is smart enough to include the delimiter between the elements yet omit from the end.

String output = streamOfModifiedPieces.collect( Collectors.joining( ", " ) );

output = aaa aaa_, bbb bbb_, ccc ccc_, ddd ddd_

One-liner

Combine all that into the promised one-liner.

String output = Arrays.stream( "aaa, bbb, ccc, ddd".split( ", " ) ).map( ( String s ) -> s + " " + s + "_" ).collect( Collectors.joining(", ") );

…or…

String output =
        Arrays
                .stream( "aaa, bbb, ccc, ddd".split( ", " ) )
                .map( ( String s ) -> s + " " + s + "_" )
                .collect( Collectors.joining( ", " ) );

aaa aaa_, bbb bbb_, ccc ccc_, ddd ddd_

2 Comments

Split uses regexp as well ( at least for complex splitting expr ). Imho this short \w+ answer is more concise and deals with more delimiter variants.
@wumpz Yes, technically speaking, the String::split method takes a regex as its argument. But in this context, that distinction is transparent to the calling programmer. Effectively, we are just passing the delimiter found in the input text. The distinction you are making would be significant only if the delimiter were coincidentally fitting the syntax of a regex — that scenario is highly unlikely.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.