diff --git a/RegExpSupport/src/org/intellij/lang/regexp/intention/ExplainRegExpIntention.java b/RegExpSupport/src/org/intellij/lang/regexp/intention/ExplainRegExpIntention.java index 81300c68bdd2..a0111bb7ad5c 100644 --- a/RegExpSupport/src/org/intellij/lang/regexp/intention/ExplainRegExpIntention.java +++ b/RegExpSupport/src/org/intellij/lang/regexp/intention/ExplainRegExpIntention.java @@ -561,13 +561,14 @@ class ExplanationVisitor extends RegExpRecursiveElementVisitor { } } else { + String set = elements.length == 1 && elements[0] instanceof RegExpCharRange range ? buildRangeText(range) : "in the set"; if (regExpClass.isNegated()) { - branch(regExpClass, new NameNode("Negated Character Class", "https://www.regular-expressions.info/charclass.html#negated"), - "matches 1 character not in the set"); + branch(regExpClass, new NameNode("Negated Character Class", "https://www.regular-expressions.info/charclass.html#negated"), + "matches 1 character not " + set); } else { - branch(regExpClass, new NameNode("Character Class", "https://www.regular-expressions.info/charclass.html"), - "matches 1 character in the set"); + branch(regExpClass, new NameNode("Character Class", "https://www.regular-expressions.info/charclass.html"), + "matches 1 character " + set); } } super.visitRegExpClass(regExpClass); @@ -584,10 +585,15 @@ class ExplanationVisitor extends RegExpRecursiveElementVisitor { @Override public void visitRegExpCharRange(RegExpCharRange range) { + if (range.getParent() instanceof RegExpClass aClass && aClass.getElements().length == 1) return; + leaf(range, new NameNode("Range", "https://www.regular-expressions.info/charclass.html"), + "matches 1 character " + buildRangeText(range)); + } + + private static @Nls @NotNull String buildRangeText(RegExpCharRange range) { RegExpChar from = range.getFrom(); RegExpChar to = range.getTo(); - leaf(range, new NameNode("Range", "https://www.regular-expressions.info/charclass.html"), - "matches 1 character from " + charText(from) + " to " + charText(to) + " (" + (to.getValue() - from.getValue() + 1) + " characters)"); + return "from " + charText(from) + " to " + charText(to) + " (" + (to.getValue() - from.getValue() + 1) + " characters)"; } @Override diff --git a/RegExpSupport/test/org/intellij/lang/regexp/intention/ExplainRegExpIntentionTest.java b/RegExpSupport/test/org/intellij/lang/regexp/intention/ExplainRegExpIntentionTest.java index 2e75f9934b2a..b164cec90486 100644 --- a/RegExpSupport/test/org/intellij/lang/regexp/intention/ExplainRegExpIntentionTest.java +++ b/RegExpSupport/test/org/intellij/lang/regexp/intention/ExplainRegExpIntentionTest.java @@ -82,6 +82,18 @@ public final class ExplainRegExpIntentionTest extends BasePlatformTestCase { \\) – matches the RIGHT PARENTHESIS character """); } + + public void testExactlyNTimes() { + doTest("[0-9]{3}-[0-9]{4}", + """ + [0-9]{3}-[0-9]{4} – matches elements in order + [0-9]{3} Quantifier (https://www.regular-expressions.info/repeat.html) – matches exactly 3 times + [0-9] Character Class (https://www.regular-expressions.info/charclass.html) – matches 1 character from DIGIT ZERO to DIGIT NINE (10 characters) + - – matches the HYPHEN-MINUS character + [0-9]{4} Quantifier (https://www.regular-expressions.info/repeat.html) – matches exactly 4 times + [0-9] Character Class (https://www.regular-expressions.info/charclass.html) – matches 1 character from DIGIT ZERO to DIGIT NINE (10 characters) + """); + } public void testComment() { doTest("(?x) implausible# inconceivable",