4

I am trying to figure out how to extract a substring from a string but the string contains a bracket, and Java then complains that it is not enclosed and if I try and escape it then complains that its not a valid escaped character.

I have the following string:

[Monitor Status](/monitors#2972550?)] · [[Edit Monitor](/monitors#2972550/edit)] · [[Related Logs](/logs?query=)]
%%%

I'm am trying to extract the number after /monitors#. The number is in two places and will always be the same in both places so I'm just trying to extract the first number.

Below is what I currently have:

Pattern pattern = Pattern.compile("[Monitor Status]/monitors#(\\d+)");                   
Matcher matcher = pattern.matcher(monitorDetails);
if (matcher.find())
{
     String monitor_id = matcher.group(1);
     monitorDetailsContainer.setVisibility(View.VISIBLE);
}

With the above, I don't have the ( between ] and /monitors but when I do Android Studio then says unclosed group. If I try and escape the slash \( it then says illegal escape character.

What I am expecting to get back is 2972550.

halfer
  • 19,824
  • 17
  • 99
  • 186
Boardy
  • 35,417
  • 104
  • 256
  • 447
  • 3
    It should be [`"\\[Monitor Status\\]\\(/monitors#(\\d+)"`](https://regex101.com/r/8iwqZg/2) – Wiktor Stribiżew Feb 26 '18 at 19:56
  • Does.....Java not support raw string literals? – zzxyz Feb 26 '18 at 20:00
  • 1
    @zzxyz No, it does not. Scala, Kotlin do. – Wiktor Stribiżew Feb 26 '18 at 20:01
  • @WiktorStribiżew Wow. I mean...even C++ does. – zzxyz Feb 26 '18 at 20:01
  • @zzxyz See [this question, too](https://stackoverflow.com/questions/1256667/raw-strings-in-java-for-regex-in-particular). BTW, C++ is not Java based while Kotlin and Scala are. Besides, Groovy has slashy strings where you can use single backslashes for regex escapes, too (and it is also Java based). – Wiktor Stribiżew Feb 26 '18 at 20:29
  • @WiktorStribiżew - Sorry for the apparent non-sequitur there. I mentioned C++ just because in terms of syntax and usage it is extremely programmer-unfriendly. (imo) – zzxyz Feb 26 '18 at 21:01
  • Hi Boardy. I'm a volunteer editor here, and we use a standard of technical writing, plus principles agreed over on _Meta_, to edit questions into shape. I notice that your questions are somewhat on the chatty side, and would ask that you keep them more succinct if you can. In particular, you have 499 posts containing thanks of various kinds, but we prefer this not to be added, [see here](https://meta.stackoverflow.com/q/288160). This [discussion here](https://meta.stackoverflow.com/q/260776) is also useful. – halfer Mar 31 '18 at 16:10

1 Answers1

6

You missed some chars on the way to the digits and failed to escape the (, ) and [, use

Pattern pattern = Pattern.compile("\\[Monitor Status]\\(/monitors#(\\d+)");                   
Matcher matcher = pattern.matcher(monitorDetails);
if (matcher.find())
{
     String monitor_id = matcher.group(1);
     monitorDetailsContainer.setVisibility(View.VISIBLE);
}

Here is a regex demo and an online Java demo.

Details

  • \[ - a [
  • Monitor Status - a literal substring
  • ] - a literal ]
  • \( - a literal (
  • / - a /
  • monitors# - a literal substring
  • (\d+) - Group 1: one or more digits.
Wiktor Stribiżew
  • 607,720
  • 39
  • 448
  • 563
  • 1
    Thanks that was what I was after. Didn't realise the square brackets had to be escaped, thought the regex pattern was only within the round brackets, anything else would be a literal string – Boardy Feb 26 '18 at 21:08