@@ -271,6 +271,9 @@ class RegExpTerm extends RegExpParent {
271271
272272 /** Holds if this regular expression term can match the empty string. */
273273 predicate matchesEmptyString ( ) { none ( ) }
274+
275+ /** Gets a string matched by this regular expression. */
276+ string getAMatch ( ) { none ( ) }
274277}
275278
276279/**
@@ -457,6 +460,20 @@ class RegExpSequence extends RegExpTerm, TRegExpSequence {
457460 override predicate matchesEmptyString ( ) {
458461 forall ( RegExpTerm child | child = this .getAChild ( ) | child .matchesEmptyString ( ) )
459462 }
463+
464+ // Why can't we use concat(...) with language[monotonicAggregates] here instead?
465+ override string getAMatch ( ) { result = this .getAMatchFromChildAtIndex ( 0 ) }
466+
467+ private string getAMatchFromChildAtIndex ( int i ) {
468+ i = this .getNumChild ( ) and result = ""
469+ or
470+ exists ( string substring , string rest |
471+ substring = this .getChild ( i ) .getAMatch ( ) and
472+ rest = this .getAMatchFromChildAtIndex ( i + 1 )
473+ |
474+ result = substring + rest
475+ )
476+ }
460477}
461478
462479pragma [ nomagic]
@@ -688,6 +705,8 @@ class RegExpCharacterClass extends RegExpTerm, TRegExpCharacterClass {
688705 override string getAPrimaryQlClass ( ) { result = "RegExpCharacterClass" }
689706
690707 override predicate matchesEmptyString ( ) { none ( ) }
708+
709+ override string getAMatch ( ) { not this .isInverted ( ) and result = this .getAChild ( ) .getAMatch ( ) }
691710}
692711
693712/**
@@ -802,6 +821,8 @@ class RegExpConstant extends RegExpTerm {
802821 override string getAPrimaryQlClass ( ) { result = "RegExpConstant" }
803822
804823 override predicate matchesEmptyString ( ) { none ( ) }
824+
825+ override string getAMatch ( ) { result = this .getValue ( ) }
805826}
806827
807828/**
@@ -851,6 +872,8 @@ class RegExpGroup extends RegExpTerm, TRegExpGroup {
851872 override string getAPrimaryQlClass ( ) { result = "RegExpGroup" }
852873
853874 override predicate matchesEmptyString ( ) { this .getAChild ( ) .matchesEmptyString ( ) }
875+
876+ override string getAMatch ( ) { result = this .getAChild ( ) .getAMatch ( ) }
854877}
855878
856879/**
0 commit comments