0

So I've a case like this

<> = 1
<><> = 2
<<>> = 2
<<test<> = 1

How do I find all of the "<>" it's inside the "<>" as well using regular expression?

Here's code that I've tried.

import java.io.IOException;
import java.util.regex.*;
import java.util.Scanner;

public class Main {
    public static void main(String[] args) throws IOException {
        Scanner s = new Scanner(System.in);
        String input = s.nextLine();

        Pattern p = Pattern.compile("<(.*?)>");
        Matcher m = p.matcher(input);

        int count = 0;
        while(m.find()){
            count++;
        }

        System.out.println(count);
    }
}
Andra
  • 1,282
  • 2
  • 11
  • 34
  • 4
    is that working or not? – The Scientific Method Sep 28 '18 at 12:03
  • 4
    That's one of the situations where [regex doesn't fit](https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags) - (arbitrary) nesting is hard if not impossible to handle correctly using regex. You're probably better off using a parser of some form. – Thomas Sep 28 '18 at 12:08
  • If you really have nested expressions you could use a stack: Push the position of the last `<` and once you encounter a `>` you can take pop the position of the last `<`. The substring from that can be easily extracted. Please note that this appraoch would give `test<` and not ` `, but i dont know what exactly you need. – Glains Sep 28 '18 at 12:15

3 Answers3

1

You can't do that with Java's regular expressions, without also employing recursion. However, a simple counting scheme works: start with level = 0, count = 0, then iterate through characters. For each <, increase level. For each >, decrease level and increment count. If level is ever negative, abort (possibly with an error), or ignore that character (depending on how you want to handle cases like <>><<>).

Amadan
  • 191,408
  • 23
  • 240
  • 301
1

start with count variable and empty stack . You should solve this using stack, iterate through each character, when you find < push it into the stack, the time you find > , pop from the stack while the stack is not empty and increase your count .

Edit: using stack

import java.util.*;
public class Test {
      public static void main(String[] args) { 
      Stack<String> myStack = new Stack<String>();
      String str = "<<test<> = 1 <><>";
      int count=0;
      char[] chs = str.toCharArray();    
          for(char ch: chs){
            if(ch == '<'){
                myStack.push(String.valueOf(ch));               
            }
            if( !myStack.isEmpty() & (ch == '>')){
                myStack.pop();
                count++;
            }
          }
      System.out.println("count = "+count); 

      }
    }

output

count = 3
The Scientific Method
  • 2,374
  • 2
  • 14
  • 25
1

You can't do that easily with a regular expression. A finite automaton is the machine that recognizes a regular expression, his memory is finite and thus cannot deal with unknowns levels of nesting.

You have to make a regex that matches a fixed depth.

Or alternatively you can make your own algorithm like so, this is very basic:

import java.lang.Math;
import java.util.*;


public class HelloWorld {
    public static void main(String[] args) {
        String s = "<<test<>";
        List <Character> l = new ArrayList <Character>();
        int count = 0;

        for (char e: s.toCharArray()) {
            if (e == '<') {
                l.add(e);
            } else if (e == '>') {
                if (l.size() > 0) {
                    l.remove(l.size() - 1);
                    count++;
                }
            }
        }

        System.out.println(count);
    }
}
lopoto
  • 231
  • 1
  • 8