9

Is it possible to use regex global g flag in java pattern ?

I tried with final Pattern pattern = Pattern.compile(regex,Pattern.DOTALL); but it do not behave like global flag.

Do we have any workaround for it in java ?

My Regex is :
private final String regex ="(public|private|protected|static|final|abstract|synchronized|volatile)\\s*([\\w<>\\[\\]]+)\\s*(\\w+)\\s*\\(([\\w\\s\\w,<>\\[\\]]*)?\\)\\s*(\\bthrows\\b)?[\\s\\w\\s,\\w]*\\{[\\n\\t]*(.+)[\\n\\t]*((return|throw){1}\\s*)(\\w*)\\s*;\\s*[\\}]";

input is the file content , something like mentioned in below regex link : https://regex101.com/r/u7vanR/3

I want java pattern to find both the occurrences, but with java regex flags its just finding the first one and not both.

Sandeep Chauhan
  • 141
  • 1
  • 2
  • 8
  • 1
    It looks like regex flavor on that page sees `.*` by default as reluctant. In Java you need to explicitly state it by `.*?` to make it match minimal amount of text. Also you don't need to surround escaped `\\}` with `[...]` (it is already escaped with ``\\``). – Pshemo Aug 04 '18 at 20:07
  • And I am not sure what is the purpose of `{1}` there. If no quantifier is specified then by default regex is searching for single match, so usually we don't need to write `{1}`. It may be useful if regex has other quantifiers like `{2}` `{3}` to show which part should exist once, twice, trice and so on. – Pshemo Aug 04 '18 at 20:11
  • here the question is not about specific regex , you can choose any other regex which matches a block of sentence/code/syntax (multiple line) in given file , i am not able to get all occurrences using java regex flag. For simple word or single line match it works using multi line option but not work for block of sentence. – Sandeep Chauhan Aug 05 '18 at 16:29
  • 1
    I wouldn't say it is not about specific regex since Java has *global* flag set on by default (what is more, you can't even turn it off). But if you are not able to match something properly, then problem most likely lies in pattern. In your case possible cause could be `.*` which by default is greedy so it attempts to match as much text as possible, which based on data from your link looks like matching all methods as *one match* (like `start of first method{ .* end of last method}`). Possible solution for that could be making `.*` reluctant with `.*?`. – Pshemo Aug 05 '18 at 17:20
  • If you are still facing some problems then to provide proper help we would need to see [mcve] and description of what you actually want to achieve. – Pshemo Aug 05 '18 at 17:21
  • @Pshemo thanks , i will try it also. i have not used .* but .+ , so do i need to change it to .+? , also {1} and \\} with [...] is not required as you correctly pointed out. but the above regex is same as mentioned in link (without java syntax) above, and matching correctly the both sections but when used in java ,not behaving same way. – Sandeep Chauhan Aug 05 '18 at 17:44
  • `.+` is also greedy by default so you may need to change it to reluctant version `.+?`. But it is hard to say if that is the only change you will need. Anyway using regex to find methods in code doesn't look right. It looks more like job for parser. Depending on your goal you may use tools like http://www.antlr.org/ (example for Java: https://stackoverflow.com/q/1931307). – Pshemo Aug 05 '18 at 18:06

2 Answers2

14

Java does not have global flag. You can get all matches via find and group.

Pattern pattern = Pattern.compile("1");
Matcher matcher = pattern.matcher("111");
while (matcher.find()) {
    System.out.println(matcher.group());
}

The output is

1
1
1
zhh
  • 2,346
  • 1
  • 11
  • 22
-1

You don't need "g" flag in Java. There are methods with the same effect, like this:

replaceAll(regex, replacement)

Mat Kamyk
  • 49
  • 1
  • 1