How to use a regex in Java to manipulate a string

Viewed 96
String s = "My cake should have ( sixteen | sixten | six teen ) candles, I love and ( should be | would be ) puff them."

Final changed string

My cake should have <div><p id="1">sixteen</p><p  id="2">sixten</p><p  id="3">six teen</p></div>  candles, I love and <div><p  id="1">should be</p><p  id="2"> would be</p> puff them

I have tried using this:

Pattern pattern = Pattern.compile("\\|\\s*(.*?)(?=\\s*\\|)");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
    System.out.println(matcher.group(1));
}
1 Answers

Use

import java.util.regex.*;

class Program
{
    public static void main (String[] args) throws java.lang.Exception
    {
        String s = "My cake should have ( sixteen | sixten | six teen ) candles, I love and ( should be | would be ) puff them.";
        Pattern pattern = Pattern.compile("\\(([^()|]*\\|[^()]*)\\)");
        Matcher matcher = pattern.matcher(s);
        StringBuffer changed = new StringBuffer();
        while (matcher.find()){
            String temp = "<div>";
            String[] items = matcher.group(1).trim().split("\\s*\\|\\s*");
            for (int i = 1; i<=items.length; i++) {
                temp += "<p id=\"" + i + "\">" + items[i-1] + "</p>";
            }
            matcher.appendReplacement(changed, temp+"</div>");
        }
        matcher.appendTail(changed);
        System.out.println(changed.toString());
    }
}

See Java proof.

Results: My cake should have <div><p id="1">sixteen</p><p id="2">sixten</p><p id="3">six teen</p></div> candles, I love and <div><p id="1">should be</p><p id="2">would be</p></div> puff them.

Regex used

\(([^()|]*\|[^()]*)\)

EXPLANATION

--------------------------------------------------------------------------------
  \(                       '('
--------------------------------------------------------------------------------
  (                        group and capture to \1:
--------------------------------------------------------------------------------
    [^()|]*                  any character except: '(', ')', '|' (0
                             or more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
    \|                       '|'
--------------------------------------------------------------------------------
    [^()]*                   any character except: '(', ')' (0 or
                             more times (matching the most amount
                             possible))
--------------------------------------------------------------------------------
  )                        end of \1
--------------------------------------------------------------------------------
  \)                       ')'

In short: Match parens with pipes, take the content with no parens and split with pipes, trim, combine into one string with loop. StringBuffer and matcher.appendReplacement do the magic with string manipulation during replacing.

Related