0
Matcher matcher = Pattern.compile("\\bwidth\\s*:\\s*(\\d+)px|\\bbackground\\s*:\\s*#([0-9A-Fa-f]+)").matcher(myString);
if (matcher.find()) {
    System.out.println(matcher.group(2));
}

Example data: myString = width:17px;background:#555;float:left; will produce null. What I wanted:

matcher.group(1) = 17
matcher.group(2) = 555

I've just started using regex on Java, any help?

meiryo
  • 9,201
  • 12
  • 42
  • 50
  • 1
    You don't any captured group 2 in your pattern. – Rohit Jain Dec 29 '12 at 16:31
  • You're requesting `String` parse, so you should use a `StringTokenizer` or another classto parse it instead of a regex. – Luiggi Mendoza Dec 29 '12 at 16:31
  • Why this question is voted down? – Walery Strauch Dec 29 '12 at 16:32
  • I thought `([0-9A-Fa-f]+)` was the second capture group. Rookie mistake? Sorry I'm new to regex. – meiryo Dec 29 '12 at 16:32
  • 1
    I don't know how to explain this other than "or" means .... "or". – Brian Roach Dec 29 '12 at 16:33
  • 3
    @meiryo.. You have used a pipe - `|`, which means `or`. So, your pattern `this|that` means `this or that`. So, if `this` is found, `that` is ignored, and if `that` is found `this` ignored. So, both the capture group are not the part of same pattern. – Rohit Jain Dec 29 '12 at 16:34
  • @RohitJain So I should be using AND OR? – meiryo Dec 29 '12 at 16:36
  • 2
    @meiryo.. No, just print `matcher.group(1)`, and instead of `if (matcher.find())` use `while (matcher.find())`. And you will get all the numbers. – Rohit Jain Dec 29 '12 at 16:37
  • 1
    As written, you have to apply your regex twice to the string, once to capture the width, once to capture the background (making sure that the width data is skipped on the second iteration). You also have the problem that you can't tell whether it just matched a width or a background because you've not captured that information. If the fields in the string were in the reverse order, you'd have no idea that the background came before the width. – Jonathan Leffler Dec 29 '12 at 17:17

2 Answers2

2

I would suggest to split things a bit up.

Instead of building one large regex (maybe you want to add more rules into the String?) you should split up the string in multiple sections:

String myString = "width:17px;background:#555;float:left;";
String[] sections = myString.split(";"); // split string in multiple sections
for (String section : sections) {

  // check if this section contains a width definition
  if (section.matches("width\\s*:\\s*(\\d+)px.*")) {
    System.out.println("width: " + section.split(":")[1].trim());
  }

  // check if this section contains a background definition
  if (section.matches("background\\s*:\\s*#[0-9A-Fa-f]+.*")) {
    System.out.println("background: " + section.split(":")[1].trim());
  }

  ...
}
micha
  • 42,796
  • 15
  • 68
  • 78
1

Here is a working example. Having | (or) in the regexp is usually confusing so I've added two more matchers to show how I would do it.

public static void main(String[] args) {
    String myString = "width:17px;background:#555;float:left";

    int matcherOffset = 1;
    Matcher matcher = Pattern.compile("\\bwidth\\s*:\\s*(\\d+)px|\\bbackground\\s*:\\s*#([0-9A-Fa-f]+)").matcher(myString);
    while (matcher.find()) {
        System.out.println("found something: " + matcher.group(matcherOffset++));
    }

    matcher = Pattern.compile("width:(\\d+)px").matcher(myString);
    if (matcher.find()) {
        System.out.println("found width: " + matcher.group(1));
    }

    matcher = Pattern.compile("background:#(\\d+)").matcher(myString);
    if (matcher.find()) {
        System.out.println("found background: " + matcher.group(1));
    }
}
Andreas Wederbrand
  • 33,680
  • 10
  • 58
  • 75