www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Pass RegexMatch to a function?

reply Gerald <gerald.b.nunn gmail.com> writes:
I have a RegexMatch that I want to pass to a function that takes 
the match and replaces various tokens in a string with the match 
and/or individual groups of the match. I'm struggling to figure 
out how to pass a RegexMatch to a function, right now I have code 
like the follows:

RegexMatch regexMatch = matchAll(urlMatch.match, 
regex(tr.pattern, tr.caseless?"i":""));
string command = replaceMatchTokens(urlMatch.match, regexMatch);

...

string replaceMatchTokens(string tokenizedText, ref RegexMatch 
match) {
     string result = tokenizedText.replace("$0", match.match);

     int i = 0;
     foreach(group; match.captures) {
         result = result.replace("$" ~ to!string(i), group);
         i++;
     }
     return result;
}

When I try to compile this, it fails with the follow on the line 
where replaceMatchTokens is declared:

Error: struct std.regex.RegexMatch(R, alias Engine = 
ThompsonMatcher) if (isSomeString!R) is used as a type

I've also tried declaring it as follows:

string replaceMatchTokens(string tokenizedText, ref 
RegexMatch!(string, ThompsonMatcher) match) {

With the following errors:

source/gx/terminix/terminal/terminal.d(1273,28): Error: struct 
std.regex.RegexMatch(R, alias Engine = ThompsonMatcher) if 
(isSomeString!R) is used as a type
source/gx/terminix/terminal/terminal.d(2701,54): Error: template 
std.regex.match cannot deduce function from argument types 
!()(RegexMatch!(string, ThompsonMatcher)), candidates are:
/usr/include/dlang/dmd/std/regex/package.d(777,13):        
std.regex.match(R, RegEx)(R input, RegEx re) if (isSomeString!R 
&& is(RegEx == Regex!(BasicElementOf!R)))
/usr/include/dlang/dmd/std/regex/package.d(785,13):        
std.regex.match(R, String)(R input, String re) if (isSomeString!R 
&& isSomeString!String)
/usr/include/dlang/dmd/std/regex/package.d(792,13):        
std.regex.match(R, RegEx)(R input, RegEx re) if (isSomeString!R 
&& is(RegEx == StaticRegex!(BasicElementOf!R)))
Aug 08 2016
parent Jonathan M Davis via Digitalmars-d-learn writes:
On Tuesday, August 09, 2016 01:07:53 Gerald via Digitalmars-d-learn wrote:
 I have a RegexMatch that I want to pass to a function that takes
 the match and replaces various tokens in a string with the match
 and/or individual groups of the match. I'm struggling to figure
 out how to pass a RegexMatch to a function, right now I have code
 like the follows:

 RegexMatch regexMatch = matchAll(urlMatch.match,
 regex(tr.pattern, tr.caseless?"i":""));
 string command = replaceMatchTokens(urlMatch.match, regexMatch);

 ...

 string replaceMatchTokens(string tokenizedText, ref RegexMatch
 match) {
      string result = tokenizedText.replace("$0", match.match);

      int i = 0;
      foreach(group; match.captures) {
          result = result.replace("$" ~ to!string(i), group);
          i++;
      }
      return result;
 }

 When I try to compile this, it fails with the follow on the line
 where replaceMatchTokens is declared:

 Error: struct std.regex.RegexMatch(R, alias Engine =
 ThompsonMatcher) if (isSomeString!R) is used as a type

 I've also tried declaring it as follows:

 string replaceMatchTokens(string tokenizedText, ref
 RegexMatch!(string, ThompsonMatcher) match) {

 With the following errors:

 source/gx/terminix/terminal/terminal.d(1273,28): Error: struct
 std.regex.RegexMatch(R, alias Engine = ThompsonMatcher) if
 (isSomeString!R) is used as a type
 source/gx/terminix/terminal/terminal.d(2701,54): Error: template
 std.regex.match cannot deduce function from argument types
 !()(RegexMatch!(string, ThompsonMatcher)), candidates are:
 /usr/include/dlang/dmd/std/regex/package.d(777,13):
 std.regex.match(R, RegEx)(R input, RegEx re) if (isSomeString!R
 && is(RegEx == Regex!(BasicElementOf!R)))
 /usr/include/dlang/dmd/std/regex/package.d(785,13):
 std.regex.match(R, String)(R input, String re) if (isSomeString!R
 && isSomeString!String)
 /usr/include/dlang/dmd/std/regex/package.d(792,13):
 std.regex.match(R, RegEx)(R input, RegEx re) if (isSomeString!R
 && is(RegEx == StaticRegex!(BasicElementOf!R)))
RegexMatch is a templated type, so if you type RegexMatch, you're not providing an actual type - just the name of the template used to generate a type. For instance, if you have struct S(T) { T member; } S would be meaningless in most cases. It would be instantiations of S such as S!int or S!string which would actually be types. Almost always, the solution when dealing with templated types is to templatize your function (you can specify the exact instantiation you're using, but that can get pretty ugly. In this case, what you probably want is something like string replaceMatchTokens(RM)(string tokenizedText, RM match) if(std.traits.isInstanceOf(RegexMatch, RM)) { ... } - Jonathan M Davis
Aug 08 2016