Performance of RegExp vs Rune Loop I was recently talking to someone about a function I wrote to mimic (very basically) the string interpolation function String.Format() found in the C# language. They mentioned that I would have performance concerns using RegExp, and that I should try to parse the string template rune by rune. So I wrote a loop the best I could to accomplish that very task. It looks alarmingly ugly (to me) and I wanted some input on the performance considerations with the loop version. As well, maybe some better suggestions on how to accomplish this function in a more sensible/clean fashion.

Here's the two different versions of the implementation:

void main() {
  String thestring = '{0} {1} {2} {3}!';
  assert(formatStringListRegExp([thestring, 'This', 'was', 'a', 'triumph']) == 'This was a triumph!');

  assert(formatStringListloop([thestring, 'This', 'was', 'a', 'triumph']) == 'This was a triumph!');
}

String formatStringListRegExp(List&lt;String&gt; args)
{
  if (args == null || args.length &lt; 2) {
    throw new ArgumentError('expected at least two paramters.');
  }
  if (args[0] is !String) {
    throw new ArgumentError('expected a string for the first paramter.');
  }
  var str = args[0];
  var inserts = args.sublist(1);
  for (var i = 0; i &lt; inserts.length; i++) {
    str = str.replaceAll('{$i}', inserts[i].toString());
  }
  return str;
}

String formatStringListLoop(List&lt;String&gt; args)
{
  if (args == null || args.length &lt; 2) {
    throw new ArgumentError('expected at least two paramters.');
  }

  if (args[0] is !String) {
    throw new ArgumentError('expected a string for the first paramter.');
  }

  var str = args[0];
  var inserts = args.sublist(1);
  StringBuffer buffer = new StringBuffer();

  for (var i = 0; i &lt; str.length; i++) {
    if (str[i] == '{' &amp;&amp; i &lt; str.length + 1) {
      var value = '';
      var count = 1;
      var number;

      while(true) {
        if (i + count &lt; str.length - 1) {
          try {
            number = int.parse(str[i + count]);
          } catch (e) {
            break;
          }
        } else {
          break;
        }

        if (number is int) {
          value += number.toString();
          count++;
        } else {
          break;
        }
      }

      if (str[i + count] == '}') {
        if (value.isNotEmpty) {
          int index = int.parse(value);
          if (index &lt; inserts.length) {
            buffer.write(inserts[index]);
            i += count;
          } else {
            buffer.write('{');
          }
        }
      }
    } else {
      buffer.write(str[i]);
    }
  }

  return buffer.toString();
}
I don't know Dart, but I haven't had any problems with Javascript regular expression speed, so I don't see why it would be a problem with Dart.

If you format strings are long -- which is probably unlikely -- then scanning the whole string once for each substitution string is not ideal. It's also buggy. Consider the calls:

formatStringListRegExp(['{0} {1}', '{1}', 'foo']) 
formatStringListRegExp(['{0} {1}', 'foo', '{0}'])


So what I'd do is this (all error checking removed for brevity):

String formatStringListRegExp(List&lt;String&gt; args)
{
  return args[0].replaceAllMapped(new RegExp(r'{(\d+)}'),
                                  (Match m) =&gt; args[int.parse(m[1])+1])
}