How to match multiple regular expressions and determine which expression matches Java

I have a Java program that goes through line by line and tries to match each line with one of four regular expressions. Depending on which expression matches, the program performs a specific action. Here is what I have:

private void processFile(ArrayList<String> lines) {
    ArrayList<Component> Components = new ArrayList<>();
    Pattern pattern = Pattern.compile(
            "Object name\\.{7}: (.++)|"
            + "\\{CAT=([^\\}]++)\\}|"
            + "\\{CODE=([^\\}]++)\\}|"
            + "\\{DESC=([^\\}]++)\\}");

    Matcher matcher;
    // Go through each line and see if the line matches the any of the regexes
    // defined
    Component currentComponent = null;

    for (String line : lines) {
        matcher = pattern.matcher(line);

        if (matcher.find()) {
            // We found a tag. Find out which one
            String match = matcher.group();

            if (match.startsWith("Obj")) {
                // We've got the object name
                if (currentComponent != null) {
                    Components.add(currentComponent);
                }
                currentComponent = new Component();
                currentComponent.setName(matcher.group(1));
            } else if (currentComponent != null) {
                if (match.startsWith("{CAT")) {
                    currentComponent.setCategory(matcher.group(2));
                } else if (match.startsWith("{CODE")) {
                    currentComponent.setOrderCode(matcher.group(3));
                } else if (match.startsWith("{DESC")) {
                    currentComponent.setDescription(matcher.group(4));
                }
            }
        }
    }

    if (currentComponent != null) {
        Components.add(currentComponent);
    }
}

As you can see, I combined the four regular expressions into one and applied the entire regular expression in the string. If a match is found, I check the beginning of the line to determine which expression was matched, and then retrieve the data from the group. In case someone is interested in running the code, some examples of the data are presented below:

Object name.......: PMF3800SN
Last modified.....: Wednesday 9 November 2011 11:55:04 AM
File offset (hex).: 00140598 (Hex).
Checksum (hex)....: C1C0 (Hex).
Size (bytes)......: 1,736
Properties........: {*DEVICE}
                    {PREFIX=Q}
                    {*PROPDEFS}
                    {PACKAGE="PCB Package",PACKAGE,1,SOT-323 MOSFET}
                    {*INDEX}
                    {CAT=Transistors}
                    {SUBCAT=MOSFET}
                    {MFR=NXP}
                    {DESC=N-channel TrenchMOS standard level FET with ESD protection}
                    {CODE=1894711}
                    {*COMPONENT}

                    {PACKAGE=SOT-323 MOSFET}
                    *PINOUT SOT-323 MOSFET
                    {ELEMENTS=1}
                    {PIN "D" = D}
                    {PIN "G" = G}
                    {PIN "S" = S}

, , startsWith.

, .

+3
3

@axtavt, , . ; . start(n) , , group(n) ( @axtavt) . :

private static void processFile(ArrayList<String> lines) {

    Pattern p = Pattern.compile(
            "Object name\\.{7}: (.++)|"
            + "\\{CAT=([^\\}]++)\\}|"
            + "\\{CODE=([^\\}]++)\\}|"
            + "\\{DESC=([^\\}]++)\\}");

    // Create the Matcher now and reassign it to each line as we go.
    Matcher m = p.matcher("");

    for (String line : lines) {
        if (m.reset(line).find()) {
            // If group #n participated in the match, start(n) will be non-negative.
            if (m.start(1) != -1) {
                System.out.printf("%ncreating new component...%n");
                System.out.printf("  name: %s%n", m.group(1));
            } else if (m.start(2) != -1) {
                System.out.printf("  category: %s%n", m.group(2));
            } else if (m.start(3) != -1) {
                System.out.printf("  order code: %s%n", m.group(3));
            } else if (m.start(4) != -1) {
                System.out.printf("  description: %s%n", m.group(4));
            }
        }
    }
}

, . , , , . , , .: D

EDIT: , . :

private static void processFile(String contents) {

    Pattern p = Pattern.compile(
            "Object name\\.{7}: (.++)|"
            + "\\{CAT=([^\\}]++)\\}|"
            + "\\{CODE=([^\\}]++)\\}|"
            + "\\{DESC=([^\\}]++)\\}");

    Matcher m = p.matcher(contents);

    while (m.find()) {
        if (m.start(1) != -1) {
            System.out.printf("%ncreating new component...%n");
            System.out.printf("  name: %s%n", m.group(1));
        } else if (m.start(2) != -1) {
            System.out.printf("  category: %s%n", m.group(2));
        } else if (m.start(3) != -1) {
            System.out.printf("  order code: %s%n", m.group(3));
        } else if (m.start(4) != -1) {
            System.out.printf("  description: %s%n", m.group(4));
        }
    }
}
+2

group() null , . , null :

Pattern pattern = Pattern.compile(
         "(Object name\\.{7}: (.++))|"
         + "(\\{CAT=([^\\}]++)\\})|"
         + "(\\{CODE=([^\\}]++)\\})|"
         + "(\\{DESC=([^\\}]++)\\})"); 
...
if (match.group(1) != null) { // Object ...
    ...
} ...

, , | .

+3

I would define a meta object that is a + runnable template. loop over lines, then loop over meta objects. if it matches, execute runnable. sort of

class Meta {
  Pattern pattern;
  Runnable runnable;
  Matcher matcher;

  Meta(Pattern p, Runnable r) {
    pattern = p;
    runnable = r;
  }
}

Meta[] metas = new Meta[] { new Meta(Pattern.compile(...), new Runnable() { ... }), new Meta(...), ... };


for (String line : lines) {
  for (Meta meta : metas) {
    final Matcher matcher = meta.pattern.matcher(line);
    if (matcher.matches()) {
      meta.matcher = matcher;
      meta.runnable.run();
    }
  }
}

here, what a Meta object would look like for the lines "Object",

Meta m = new Meta(Pattern.compile("Object name\\.{7}: (.++)", new Runnable() {
  // We've got the object name
  if (currentComponent != null) {
    Components.add(currentComponent);
  }
  currentComponent = new Component();
  currentComponent.setName(matcher.group(1));
});
0
source

All Articles