-1

I have strings that have a pattern like the following ones:

  • PSHELF-2[PSHELF-MF-6RU]
  • SHELF-5[SHELF-M6]
  • SHELF-6[SHELF-M15]
  • SHELF-6[SHELF-M15]

I'd like to get the info highlighted.
To do so I use the following regex:

(.*SHELF)-(.*)\[.*SHELF-(.*)\]

I tested it with regex101

If I try to implement the same login on Java

Pattern pattern = Pattern.compile("(.*SHELF)-(.*)\\[.*SHELF-(.*)\\]");
Matcher matcher = pattern.matcher(inputString);
String group1 = matcher.group(1);
String group2 = matcher.group(2);
String group3 = matcher.group(3);

I got the following error:

java.lang.IllegalStateException: No match found

Why is that?

gixlg
  • 1,193
  • 1
  • 9
  • 21
  • 6
    You need to call `matcher.find()` first and if it returned true the groups will be initialized and accessible. From the JavaDoc on `group(int)`: " If no match has yet been _attempted_ ..." - and on `find()`: "If the match succeeds then more information can be obtained via the start, end, and group methods.". – Thomas May 10 '19 at 15:22
  • 1
    or `if (matcher.matches()) { matcher.group(1);}` – Conffusion May 10 '19 at 15:30
  • 1
    Perhaps like `([A-Z]+)-\d+\[\1-([A-Z\d]+(?:-[A-Z\d]+)?)\]` and use capturing group 1 and 2 [demo](https://regex101.com/r/4DSd28/1) – The fourth bird May 10 '19 at 15:39

1 Answers1

-1

This post answers your original question.


This expression creates capturing groups and returns your desired outputs in multiple forms:

(([A-Z]+)-([0-9]+))\[([A-Z]+)-([A-Z0-9-]+)(\])

which you can additionally simplify it, if you wish.

enter image description here

Java Test

import java.util.regex.Matcher;
import java.util.regex.Pattern;

final String regex = "(([A-Z]+)-([0-9]+))\\[([A-Z]+)-([A-Z0-9-]+)(\\])";
final String string = "PSHELF-2[PSHELF-MF-6RU]\n"
     + "SHELF-5[SHELF-M6]\n"
     + "SHELF-6[SHELF-M15]\n"
     + "SHELF-6[SHELF-M15]";
final String subst = "\\1 \\4";

final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);

// The substituted value will be contained in the result variable
final String result = matcher.replaceAll(subst);

System.out.println("Substitution result: " + result);

JavaScript Demo

const regex = /(([A-Z]+)-([0-9]+))\[([A-Z]+)-([A-Z0-9-]+)(\])/gm;
const str = `PSHELF-2[PSHELF-MF-6RU]
SHELF-5[SHELF-M6]
SHELF-6[SHELF-M15]
SHELF-6[SHELF-M15]`;
const subst = `\nGroup 1: $1\nGroup 2: $2\nGroup3: $3\nGroup 4: $4\nGroup 5: $5`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

RegEx Descriptive Graph

This graph shows how the expression would work and you can visualize other expressions in this link:

enter image description here

Basic Performance Test

This JavaScript snippet shows the expression performance using a simple 1-million times for loop.

const repeat = 1000000;
const start = Date.now();

for (var i = repeat; i >= 0; i--) {
 const string = 'PSHELF-2[PSHELF-MF-6RU]';
 const regex = /(([A-Z]+)-([0-9]+))\[([A-Z]+)-([A-Z0-9-]+)(\])/gm;
 var match = string.replace(regex, "\nGroup #1: $1\nGroup #2: $2 \nGroup #3: $3 \nGroup #4: $4\nGroup #5: $5\n");
}

const end = Date.now() - start;
console.log("YAAAY! \"" + match + "\" is a match  ");
console.log(end / 1000 + " is the runtime of " + repeat + " times benchmark test.  ");
Emma
  • 27,428
  • 11
  • 44
  • 69