【问题标题】:Regex (C#) - how to match variable names that start with a colon正则表达式 (C#) - 如何匹配以冒号开头的变量名
【发布时间】:2018-03-08 05:07:03
【问题描述】:

我需要在我试图解析的一些表达式中区分变量名和非变量名。变量名以冒号开头,可以有(但不能以)数字,并有下划线。所以有效的变量名是:

:x :_x :x2 :alpha_x   // etc

然后我必须在表达式中挑选出不以冒号开头的其他单词。所以在下面的表达式中:

:result = median(:x,:y,:z)

变量是 :result、:x、:y 和 :z,而其他非变量词是中位数。

我选择变量名的正则表达式是(这可行):

:[a-zA-Z_]{1}[a-zA-Z0-9_]*

但我无法弄清楚如何获得非可变词。我的正则表达式是:

(?<!:)([a-zA-Z_]{1}[a-zA-Z0-9_]*)

问题是,匹配只排除 : 之后的第一个字符,如下所示:

【问题讨论】:

  • 那么你的非可变词之前需要一个非 a-z 是真的吗?所以: this 应该匹配this

标签: c# regex


【解决方案1】:

(?&lt;!:)([a-zA-Z_]{1}[a-zA-Z0-9_]*) 正则表达式仍然匹配部分变量字,因为(?&lt;!:) 确保在当前位置的左侧没有:,然后匹配标识符而不检查字边界。所以,在:alpha 中,lpha 是匹配的,因为l 前面有一个不是: 的字符。

因此问题很容易通过在[a-zA-Z_]之前添加一个单词边界来解决:

var words = Regex.Matches(s, @"(?<!:)\b[a-zA-Z_]\w*", RegexOptions.ECMAScript)
        .Cast<Match>()
        .Select(x => x.Value)
        .ToList();

请参阅regex demo。请注意,您不需要使用捕获组来包装整个模式。

模式详情

  • (?&lt;!:) - 确保当前位置左侧没有:
  • \b - 单词边界:确保当前位置左侧没有字母、数字或 _
  • [a-zA-Z_] - 匹配一个 ASCII 字母或 _
  • \w* - 0+ ASCII 字母、数字或 _必须与 ECMAScript 选项一起使用以仅匹配 ASCII 字母和数字,并使单词边界仅处理 ASCII)

【讨论】:

    【解决方案2】:

    以下模式似乎有效:

    (?<=[^A-Za-z0-9_:])[a-zA-Z_]{1}[a-zA-Z0-9_]*
    

    lookbehind (?&lt;=[^A-Za-z0-9_:]) 断言前面的内容既不是变量名中允许的字符,也不是冒号。这将标记一个非可变词的开始。

    Demo

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-12
      • 2021-09-26
      • 2019-06-01
      • 1970-01-01
      • 2013-11-23
      相关资源
      最近更新 更多