【问题标题】:Preventing Regex skipping the value in the middle防止正则表达式跳过中间的值
【发布时间】:2020-03-29 09:31:25
【问题描述】:

我正在尝试使用以下正则表达式在源代码文件中捕获一些字符串值

[\s\"\']{1}([A-Za-z0-9\_\-]{1,})[\s\"\']{1}

对于类似这样的变量:

var components = 'string_1 string_2 string_3';

但正则表达式仅捕获 string_1string_3 跳过 string_2

我相信这是因为在捕获string_1 值时,正则表达式实际上检测到'string_1(注意'space)和string_3'(还要注意space') 最终以 string_2 两边都没有,所以它不会被捕获。

如何捕获所有三个值。

请注意,正则表达式需要捕捉以下场景:

"string_1"
'string_1'
"string_1 string2"
'string_1 string2'
"string_1 string2 string3"

等等……

也不需要匹配

$string_1
#string_1$
string_1
//string_1
/*string_1
\string_1
!string_1

等等……

只有当它们在单引号、双引号、空格或这三者的混合对之间时,我才需要捕获这些值。

【问题讨论】:

  • 您当前的模式无效,括号不匹配
  • 仅供参考 {1} 绝对不会做任何事情,除了制造噪音。下划线不需要转义,- 在字符类中的第一个或最后一个(你的字符类)也不需要转义。请更正语法错误:您的字符类格式错误 - 如果确实是您的意图,您有一个闭合的 round 括号而不是闭合的 square 括号。

标签: regex


【解决方案1】:

如果您的正则表达式引擎是 PCRE (PHP),则可以使用以下正则表达式:

(?:\"|\G) *\K\w+(?=.*\")|(?:\'|\G) *\K\w+(?=.*\') 

Demo

正则表达式引擎执行以下操作:

(?:          # begin a non-capture group
  \"         # match double-quote
 |           # or
 \G          # continue from where last match ended
)            # end non-capture group
\ *          # match 0+ spaces
\K           # forget everything matched so far
\w+          # match 1+ word chars
(?=          # begin positive lookahead
  .*         # match 0+ chars in same line
  \"         # match double quote
)            # end positive lookahead
|            # or 
(?:\'|\G)    # as above except single rather than double quote
\ *\K\w+     # as above
(?=.*\')     # as above except single rather than double quote

【讨论】:

  • 这太棒了。但它匹配分布在多行中的字符串。请参阅regex101.com/r/z68pq5/1。是否可以修改为不接受换行符或除单引号、双引号和常规空格以外的任何字符?
  • 我没有得到你在第二句话中提到的结果,但我将允许的字符更改为单词字符 (\w)。那样行吗。 Demo
  • 这是完美的。谢谢。
【解决方案2】:

如何捕获所有三个值。

使用 ([^\W]+) 和 1 到多个匹配项将具有每个非间隔项目。

基本上是说匹配可用字符集\w的任何内容,方法是在1对多的集合中使用^(不)\W(任何非字符) +.

【讨论】:

  • 感谢您的快速回答。我已经更新了原始问题以添加更多细节和说明。不幸的是,这也匹配 $string_1...
【解决方案3】:

试试这个:/(\b\w+?\b)+?/gm

演示:https://regex101.com/r/W5kD9S/5

解释:

  • \b 在单词边界处断言位置
  • \w 匹配任何单词字符(等于[a-zA-Z0-9_]
  • +? 匹配一次到无限次,尽可能少,根据需要扩展(懒惰)

更新:

我已更新原始问题以添加更多细节和说明。不幸的是,这也匹配 $string_1...

好的,那你可以试试这个:^(?:'|")(.*)?(?:'|")$

演示:https://regex101.com/r/W5kD9S/4

【讨论】:

  • 感谢您的快速回答。我已经更新了原始问题以添加更多细节和说明。不幸的是,这也匹配 $string_1...
  • @monroo 没问题。感谢您的反馈。我更新了我的答案。
【解决方案4】:

基于 PCRE 的 RegEx 风格的表达式略有不同,它依赖于捕获分隔符,提前检查是否可以在可变数量的允许字符后再次找到相同的分隔符,并且只匹配允许的单词,只要它们跟随开始分隔符。

/(['"])(?=[\w ]+\1)\K\w+|\G \K\w+/g

\K 用于从返回的匹配字符串中删除其前面的字符。

regex demo

【讨论】:

    猜你喜欢
    • 2016-06-07
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多