{"record":{"id":"a41fe2435b46928c","repo":"languagetool-org/languagetool","slug":"got-matcher-groupcount-groups-for-regex-a41fe2","errorCode":null,"errorMessage":"Got \" + matcher.groupCount() + \" groups for regex '\" + pattern.pattern() + \"', expected 2","messagePattern":"Got \" \\+ matcher\\.groupCount\\(\\) \\+ \" groups for regex '\" \\+ pattern\\.pattern\\(\\) \\+ \"', expected 2","errorType":"validation","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"languagetool-core/src/main/java/org/languagetool/rules/PartialPosTagFilter.java","lineNumber":84,"sourceCode":"      String suffix = \"\";\n\n      if (args.containsKey(\"prefix\")) {\n          prefix = args.get(\"prefix\");\n      };\n\n      if (args.containsKey(\"suffix\")) {\n          suffix = args.get(\"suffix\");\n      };\n\n     \n    String token = prefix + patternTokens[tokenPos - 1].getToken() + suffix;\n    \n    Matcher matcher = pattern.matcher(token);\n    if ((matcher.groupCount() != 1) && !(two_groups_regexp)) {\n      throw new RuntimeException(\"Got \" + matcher.groupCount() + \" groups for regex '\" + pattern.pattern() + \"', expected 1\");\n    }\n    if ((matcher.groupCount() != 2) && (two_groups_regexp)) {\n      throw new RuntimeException(\"Got \" + matcher.groupCount() + \" groups for regex '\" + pattern.pattern() + \"', expected 2\");\n    }\n    if (matcher.matches()) {\n      String partialToken = matcher.group(1);\n      if (matcher.groupCount() == 2) {\n        partialToken += matcher.group(2);\n      } \n      List<AnalyzedTokenReadings> tags = tag(partialToken);\n      if (tags != null && partialTagHasRequiredTag(tags, requiredTagRegexp, negatePos)) {\n        return match;\n      }\n      return null;\n    }\n    return null;\n  }\n\n  private boolean partialTagHasRequiredTag(List<AnalyzedTokenReadings> tags, String requiredTagRegexp, boolean negatePos) {\n    // Without negate_pos=yes: return true if any postag matches the regexp.\n    // With negate_pos=yes:    return true if there are postag and none them matches the regexp.","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/languagetool-org/languagetool/blob/2e990059ce67d5e2a0f7f7ca5d31160c6709df4b/languagetool-core/src/main/java/org/languagetool/rules/PartialPosTagFilter.java#L66-L102","documentation":"Companion to error 54: when the filter arg two_groups_regexp is set, PartialPosTagFilter requires the regex to have exactly 2 capturing groups (second group appended to the partial token). This RuntimeException is thrown when groupCount() != 2 while two_groups_regexp is true.","triggerScenarios":"Declaring two_groups_regexp in the filter args but supplying a regex with fewer or more than two capturing groups.","commonSituations":"Enabling two_groups_regexp for an infix/prefix match but leaving the regex from a single-group example; escaping mistakes that turn '(' groups into literals.","solutions":["Make the regex contain exactly two capturing groups, e.g. 'pre(.*)post(.*)'.","If only one group is needed, remove the two_groups_regexp arg instead.","Verify group count programmatically before deploying the rule."],"exampleFix":"<!-- before -->\n<filter class=\"...PartialPosTagFilter\" args=\"no:1 two_groups_regexp regexp:(.*)ing postag_regexp:VBZ\"/>\n<!-- after -->\n<filter class=\"...PartialPosTagFilter\" args=\"no:1 two_groups_regexp regexp:(.*)(ing) postag_regexp:VBZ\"/>","handlingStrategy":"validation","validationCode":"java.util.regex.Pattern p = java.util.regex.Pattern.compile(regexp);\nif (twoGroups && p.matcher(\"\").groupCount() != 2) {\n  throw new IllegalArgumentException(\"two_groups_regexp requires exactly 2 capturing groups\");\n}","typeGuard":null,"tryCatchPattern":"try {\n  return filter.acceptRuleMatch(match, args, pos, tokens, tokenPositions);\n} catch (RuntimeException e) {\n  throw new RuleFormatException(\"Bad two_groups_regexp pattern: \" + e.getMessage(), e);\n}","preventionTips":["Only set two_groups_regexp when the regex really has 2 groups","Count '(' occurrences (excluding escaped \\( and (?:) before setting the flag","Keep single-group and two-group rule variants in separate test files"],"tags":["java","languagetool","regex","capture-groups"],"backgroundTag":"invalid-regex-pattern","analyzedSha":"2e990059ce67d5e2a0f7f7ca5d31160c6709df4b","analyzedAt":"2026-09-06T09:20:17.015Z","contentChangedAt":"2026-09-06T09:20:17.015Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}