【问题标题】:Match words and full stops, but not the trailing full stop匹配单词和句号,但不匹配尾随句号
【发布时间】:2018-12-14 19:38:03
【问题描述】:

我正在尝试匹配$word1.word2.word3 类型的字符串,其中包含点,但不应以点结尾。

换句话说:

$context.abc.value, $context.abc.value.random() - 应该匹配完整的字符串

$context.abc.value. - 应该匹配除最后一个字符(点)以外的所有字符。

我现在的正则表达式是:

(?:^|\s)\$(?!\d)[\w.\[\]\(\)]+

这是一个可以玩的小提琴:https://regex101.com/r/PxCtUv/1

如何避免匹配尾随的点字符?

【问题讨论】:

    标签: javascript regex


    【解决方案1】:

    如果您愿意,可以不使用正则表达式:

    const data = [
        'context.abc.value',
        '$context.abc.value.random()',
        '$context.abc.value.'
    ];
    
    const filtered = data.filter(item => Array.from(item).pop() !== '.');
    
    // [ 'context.abc.value', '$context.abc.value.random()' ]
    

    【讨论】:

      【解决方案2】:

      使用以下一个:

      \$(?!\d)[\w]+([.]{0,1}[\w()]+)+
      

      您可以通过以下方式尝试:https://regex101.com/r/2ONUHj/1

      • 这将不匹配$ 符号之前的空格。
      • 它将只允许一个.

      这里可能还有很多其他的边缘情况没有定义。

      更多详情请使用https://regexr.com/上的说明。

      【讨论】:

      • 有趣。但是,请注意您遗漏了原始正则表达式匹配的 []。您的正则表达式可以“整理”为\$[a-zA-Z_]\w*(?:\.[\w()]+)*
      【解决方案3】:

      您可以将最后一个[a.]+ 模式“分解”为[a.]*[a]

      (?:^|\s)\$(?!\d)[\w.[\]()]*[\w[\]()]
                      ^^^^^^^^^^^^^^^^^^^^
      

      请参阅regex demo

      详情

      • (?:^|\s) - 匹配字符串开头 (^) 或 (|) 空格 (\s) 的非捕获组
      • \$ - 一个 $ 字符
      • (?!\d) - 如果在 $ 字符之后有一个数字,则匹配失败的负前瞻
      • [\w.[\]()]* - 零个或多个单词,.[]() 字符
      • [\w[\]()] - 一个字,.[]() 字符。

      【讨论】:

      • 请注意,在[...](一个字符类)内部,[() 失去了它们的“特殊”含义,它们不必在那里转义。它甚至在使用u 标志编译的 ES6 正则表达式中被视为错误。另外,请查看an alternative regex。随意进一步精确。