From f84e3dc684cba30d324bdb65b9c97ca63e15e57c Mon Sep 17 00:00:00 2001 From: Peter Kriens Date: Sun, 24 Dec 2023 14:28:20 +0100 Subject: [PATCH] small corrections on RE --- Signed-off-by: Peter Kriens Signed-off-by: Peter Kriens --- aQute.libg/src/aQute/libg/re/Catalog.java | 74 ++++++++++++++++++++--- aQute.libg/src/aQute/libg/re/RE.java | 2 + aQute.libg/test/aQute/libg/re/RETest.java | 3 + 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/aQute.libg/src/aQute/libg/re/Catalog.java b/aQute.libg/src/aQute/libg/re/Catalog.java index 70e77a3fdd..ec9ba56a44 100644 --- a/aQute.libg/src/aQute/libg/re/Catalog.java +++ b/aQute.libg/src/aQute/libg/re/Catalog.java @@ -54,6 +54,7 @@ */ public class Catalog { + /** * If this class is extended, the named fields in that class can be used in * named groups. This method will lookup the name of a field and create a @@ -908,6 +909,8 @@ public static RE string(char delimeter) { final public static RE empty = new REImpl(""); final public static C tab = new Special("\t"); final public static RE number = some(digit); + public static C hexdigit = cc("0-9A-F"); + public static RE hexnumber = some(hexdigit); final public static C minus = new CharacterClass("-"); final public static C dquote = new CharacterClass("\""); final public static C squote = new CharacterClass("'"); @@ -923,6 +926,7 @@ public static RE string(char delimeter) { final public static C javaJavaIdentifierStart = new Predefined("javaJavaIdentifierStart", true); final public static C javaJavaIdentifierPart = new Predefined("javaJavaIdentifierPart", true); final public static RE javaId = seq(javaJavaIdentifierStart, set(javaJavaIdentifierPart)); + final public static RE fullyQualifiedName = seq(javaId, set(dot, javaId)); final public static RE startOfLine = new Boundary("^"); final public static RE endOfLine = new Boundary("$"); final public static RE wordBoundary = new Boundary("\\b"); @@ -1059,6 +1063,37 @@ public int end() { return end < 0 ? end = matcher.start(name) : end; } } + class MatchGroupImplIndex extends Base implements MatchGroup { + final int name; + String value; + int start = -1; + int end = -1; + + MatchGroupImplIndex(int name, String value) { + this.name = name; + this.value = value; + } + + @Override + public String name() { + return Integer.toString(name); + } + + @Override + public String value() { + return value == null ? value : matcher.group(name); + } + + @Override + public int start() { + return start < 0 ? start = matcher.start(name) : start; + } + + @Override + public int end() { + return end < 0 ? end = matcher.end(name) : end; + } + } class MatchImpl extends Base implements Match { Map matchGroups; Map matchValues; @@ -1089,15 +1124,17 @@ public Map getGroups() { if (matchGroups == null) { if (groups == null) matchGroups = Collections.emptyMap(); - Map result = new TreeMap<>(); - for (String name : groups) { - String value = matcher.group(name); - if (value != null) { - MatchGroupImpl mg = new MatchGroupImpl(name, value); - result.put(name, mg); + else { + Map result = new TreeMap<>(); + for (String name : groups) { + String value = matcher.group(name); + if (value != null) { + MatchGroupImpl mg = new MatchGroupImpl(name, value); + result.put(name, mg); + } } + matchGroups = Collections.unmodifiableMap(result); } - matchGroups = Collections.unmodifiableMap(result); } return matchGroups; } @@ -1138,6 +1175,19 @@ public String tryMatch(RE expected) { return null; } + @Override + public Optional group(int group) { + + if (matcher.groupCount() < group) + return Optional.empty(); + + String value = matcher.group(group); + if (value == null) + return Optional.empty(); + + return Optional.of(new MatchGroupImplIndex(group, value)); + } + } return Optional.of(new MatchImpl()); } else @@ -1501,11 +1551,11 @@ static class Option extends REImpl implements F { final EnumSet negative; Option(EnumSet positive, EnumSet negative, RE... res) { - this(toGroupedString(false, res), positive, negative); + this(toGroupedString(false, res), positive, negative, names(res)); } - Option(String ungrouped, EnumSet p, EnumSet n) { - super(ungrouped); + Option(String ungrouped, EnumSet p, EnumSet n, String... names) { + super(ungrouped, names); this.positive = p == null ? NONE_OF : p; this.negative = n == null ? NONE_OF : n; } @@ -1721,4 +1771,8 @@ static boolean isWhiteSpace(RE re) { }; } + public static RE re(String regex) { + return new REImpl(regex); + } + } diff --git a/aQute.libg/src/aQute/libg/re/RE.java b/aQute.libg/src/aQute/libg/re/RE.java index 9dcb15f9b0..11c1052cef 100644 --- a/aQute.libg/src/aQute/libg/re/RE.java +++ b/aQute.libg/src/aQute/libg/re/RE.java @@ -321,6 +321,8 @@ default boolean check(RE expected) { * @param match the RE to match return a string when matched or null */ String tryMatch(RE match); + + Optional group(int group); } /** diff --git a/aQute.libg/test/aQute/libg/re/RETest.java b/aQute.libg/test/aQute/libg/re/RETest.java index 5019dd0ef7..25975ad868 100644 --- a/aQute.libg/test/aQute/libg/re/RETest.java +++ b/aQute.libg/test/aQute/libg/re/RETest.java @@ -399,6 +399,9 @@ public void testNamed() { assertThat(test3.toString()).isEqualTo("(?:(?a)(?(?b)))"); assertThat(test3.getGroupNames()).containsExactlyInAnyOrder("foo", "bar", "xyz"); + RE testOption = Catalog.caseInsenstive(test, test2, test3); + assertThat(testOption.getGroupNames()).containsExactlyInAnyOrder("foo", "bar", "xyz"); + } @Test