【问题标题】:Regular expresion with a specific character and without another具有特定字符且没有其他字符的正则表达式
【发布时间】:2021-08-18 00:22:51
【问题描述】:

我正在尝试在我用 Dart 编写的宏生成器中实现转义字符功能。例如,我希望程序抓取字符串中所有出现的“&param”并将其替换为“John”,除非“&”字符前面有转义字符“\”。 示例:“我的名字是 &param,我的参数叫做 \&param。” -> “我的名字是 John,我的参数被称为 &param”。 什么是正则表达式来捕获所有包含 '&' 的子字符串,然后是我的参数名称,并且没有前面的 '\'?

【问题讨论】:

  • 问题变得更加复杂。您将如何从字面上放置反斜杠和 &param 的扩展值?也许 \\&param ?好的,那么你需要注意两个。不用等待,你如何做一个反斜杠,然后是文字 &param。哦,那将是 \\\&param。你真的需要做一个完整的从左到右的解析。

标签: regex dart regular-language


【解决方案1】:

可以匹配,甚至避免反斜杠转义,如:

var re = RegExp(r"(?<!(?:^|[^\\])(?:\\{2})*\\)&\w+");

这使用否定的lookbehind查找&amp;后跟单词字符,并且前面没有奇数个反斜杠。

更有可能,您还想识别双反斜杠并将它们转换为单反斜杠。如果您尝试查找所有匹配项,这实际上更容易,因为您知道所有前面的双反斜杠都是较早匹配项的一部分:

var re = RegExp(r"\\\\|(?<!\\)&\w+");

当用作re.allMatches 时,将查找所有出现的\\&amp;word,其中后者前面没有奇数个反斜杠。

var _re = RegExp(r"\\\\|(?<!\\)&(\w+)");
String template(String input, Map<String, String> values) {
  return input.replaceAllMapped(_re, (m) {
    var match = m[0]!;
    if (match == r"\\") return r"\";
    var replacement = values[m[1]!];
    if (replacement != null) return replacement;
    // do nothing for undefined words.
    return match;
  });
}

(如果参数可以出现在其他字符旁边,例如 &amp;{amount)USD,您可能还希望允许类似 &amp;{foo} 的内容。

【讨论】:

    【解决方案2】:

    要在&amp;param 匹配非反斜杠字符时保留该字符,您需要使用所谓的捕获组。这些是括号内正则表达式的子表达式。要在 Dard 中使用捕获组,您需要使用 replaceAllMapped 方法。我们也有模板以&amp;param 开头的情况,在这种情况下我们匹配字符串的开头。

    试试这个:

    void main() {
        final template = 'My name is &param and my parameter is called \\&param.';
        final populatedTemplate = template.replaceAllMapped(RegExp(r'(^|[^\\])&param\b'),  (match) {
            return '${match.group(1)}John';
        });
        final result = populatedTemplate.replaceAll(RegExp(r'\\&param\b'),  'John');
        print(result);
    }
    

    【讨论】:

      猜你喜欢
      • 2021-03-05
      • 2021-09-06
      • 2022-11-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多