0

I have a string as follows:

"This is @awesome @dude"

From this string i want to extract awesome and dude and create a string

 output==> "awesome,dude"

So my code is like following:

Matcher matcher = Pattern.compile("(?<=@)\\w+").matcher(textStr);
while (matcher.find()){
    mergedStr += matcher.group() +",";
}

But this creates an artifact in the end

output==> "awesome,dude,"  //<-- egghh comma.. in the end

What is a better way to solve this out.

4
  • 1
    You're adding the extra comma with the mergedStr += matcher.group() +","; line. Commented Jun 4, 2013 at 21:04
  • The problem is not on the regex, just on the way you build the result. Commented Jun 4, 2013 at 21:04
  • Well, you can either truncate the extraneous comma or never add it in the first place. One way to do the latter is to do the first word outside the loop, then add the comma at the top of the loop. Commented Jun 4, 2013 at 21:04
  • @rajah9 the question is about how to not add that extra comma at the end. Commented Jun 4, 2013 at 21:05

5 Answers 5

3

Another approach:

boolean needComma = false;
while (blah, blah, blah) {
    if (needComma) {
        string += ",";
    }
    string += word;
    needComma = true;
}

But there are a dozen different approaches.

Sign up to request clarification or add additional context in comments.

Comments

1

This is one option:

Matcher matcher = Pattern.compile("(?<=@)\\w+").matcher(textStr);
while (matcher.find()){
    if (!mergedStr.isEmpty())
      mergedStr += ",";
    mergedStr += matcher.group();
}

9 Comments

+1 for this simple solution but please avoid if statements without curly brackets. It is a quite bad practice.
That solves the problem, but I think this would be a better answer if you mentioned that (s)he should use a StringBuilder. :-)
@Dukeling if you want to avoid curly brackets why not put the THEN part of the statement on the same line as the IF part? (Im not a wild fan of that either but it is at least less easy to misread)
@RichardTingle Because I find that more difficult to read - somewhere in the middle of the line the THEN part starts (so I have to look for it), rather than 1 "tab" from the if (then I can instantly see it). But this is not really the place to discuss coding standards or to not upvote people (@adenoyelle (apologies if that was an incorrect assumption)) because they don't conform to your coding standards, but you would've if they had.
@ruakh Fair point, but for all but the most performance-critical task, I find it to be a micro-optimization. I'd rather stick to slightly simpler code. Not to mention that the optimizer may actually be able to convert the one to the other.
|
1

Here is another common approach:

Matcher matcher = Pattern.compile("(?<=@)\\w+").matcher(textStr);
StringBuilder sb = new StringBuilder();
while (matcher.find()){
    sb.append(matcher.group()).append(",");
}
return sb.toString().replaceAll(",$", "");

If you don't want to use a regex, you could do it like this:

Matcher matcher = Pattern.compile("(?<=@)\\w+").matcher(textStr);
StringBuilder sb = new StringBuilder();
while (matcher.find()){
    sb.append(matcher.group()).append(",");
}
if (sb.length() == 0) {
    return "";
}
else {
    return sb.toString().substring(0, sb.length() - 1);
} 

5 Comments

Does not work because String.replace does not accept regular expressions. If you use replaceAll instead, it works.
Good point... Not sure how I forgot that (too much JavaScript lately). Corrected.
return mergedStr.substring(0, mergedStr.length()-1); may be a better option.
@Dukeling - That would not work if the StringBuilder is empty... Otherwise I would have used it. The choice was to add an if/else (plus braces;) or to use a regex. Obviously there are about a dozen common ways that this situation is handled.
Oh, right, forgot about that. return mergedStr.substring(0, Math.max(0, mergedStr.length()-1)); is another option, albeit somewhat confusing, but the regex is probably simpler, though not everyone may understand regex.
1

A useful pattern that I often use for this kind of thing is to append the first item, and then append the remainder of the items preceded by the separator. This avoids unnecessary conditionals in loops or postprocessing to remove trailing separators.

I know, microoptimizations blah, blah, sixth circle of hell, blah, blah, but just including here for your amusement:

    Matcher matcher = Pattern.compile("(?<=@)\\w+").matcher(textStr);
    StringBuilder mergedStr = new StringBuilder();
    if (matcher.find()) {
      mergedStr.append(matcher.group());
      while (matcher.find()) {
        mergedStr.append(',').append(matcher.group());
      }
    }
    return mergedStr.toString();

Also, I'm not 100% convinced that replacing a quadratic algorithm (string concatenation) with a linear algorithm (StringBuilder) qualifies as a microoptimization in the bad sense.

Comments

0
String input = "@awesome@dude";
        List<String> strSplit = new ArrayList<String>();
        String result = "";

        Matcher matcher = Pattern.compile("(?<=@)\\w+").matcher(input);
        while (matcher.find()){
            strSplit.add(matcher.group());

        }
        for(int j = 0; j< strSplit.size(); j++){
            result = result + strSplit.get(j);
            if(j < strSplit.size() -1){
                result = result+",";
            }
        }
        System.out.println("Result : " + result);

Comments

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.