0

I have a pattern and a string as an input, I'm looking to find that pattern N times in the input but if doesn't work.

I tried with following pattern:

    private static Pattern test = Pattern.compile("(<tag>)(.*)(</tag>)");
    private static String input = "<tag>hello</tag>blablabla<tag>world</tag>";

    public static void main(String[] args) {
        MyClass myClass = new MyClass();
        System.out.println(myClass.change(input));
    }

    public static String change(String text) {
    StringBuilder s = new StringBuilder();

    try {
        Matcher m = test.matcher(text);
        int pos = 0;
        while (m.find()) {
            s.append(text, pos, m.start());
            pos = m.end();
            s.append("&&" + m.group(2) + "&&");
        }
        s.append(text, pos, text.length());

    } catch (Exception e) {
        System.out.println("Exception " + e);
    }
    return s.toString();
}

this is what I'm getting:

    &&hello</tag>blablabla<tag>world&&

and this is the result what I want:

    &&hello&&blablabla&&world&&

Any idea? Thanks

Julio
  • 429
  • 2
  • 16
  • It looks as though what you are doing can be contracted to `input.replaceAll("(?s)(.*?)", "&&$1&&")` – Wiktor Stribiżew Dec 26 '19 at 17:32
  • Just make your regex ungreedy by using `.*?`. Problem solved! – csabinho Dec 26 '19 at 17:33
  • I tried this but it doesn't work: "()(.*)().*?" – Julio Dec 26 '19 at 17:41
  • 1
    Of course this won't work. You'll have to use `()(.*?)()`. – csabinho Dec 26 '19 at 17:51
  • yeah you're right, thanks – Julio Dec 26 '19 at 18:09
  • Mandatory [link](https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454). – Pshemo Dec 26 '19 at 18:53
  • `this is the result what I want: &&hello&&blablabla&&world&&` No because there is no open / close tag pair surrounding `blablabla` –  Dec 26 '19 at 19:28
  • There is no need to do loops, they can all be found with a single match using this `(?s)(?:.*?(.*?))+` then use the _Capture Collection_ on group 1. If 10 is _required_, then this regex `(?s)(?:.*?(.*?)){10}` –  Dec 26 '19 at 19:33
  • Also, specific tag matching requires a more robust regex, generally like this `(?s)<(tag)(?:\s+(?>".*?"|'.*?'|(?:(?!/>)[^>])?)+)?\s*>(.*?)\1\s*>`. And for the capture collection single match for group 2 its this `(?s)(?:.*?<(tag)(?:\s+(?>".*?"|'.*?'|(?:(?!/>)[^>])?)+)?\s*>(.*?)\1\s*>)+` This way different tags can be used, just add to the list inside capture group 1 `(tag|more tags)`, etc... If specific attributes are required inside the tags, that can also be done with a slight modified regex. –  Dec 26 '19 at 19:49

0 Answers0