查看^\s*(_?)(\S+?)\1\s*$中的injector.js
正则表达式。
我已经能够理解字符串scope :with_tagged_users, -> { Node.where('cached_num_user_tags > 0') }
是如何匹配的。第一个捕获组由_non_
组成,第二个组由_
组成,对第一个捕获组结果的引用为您提供non
。因此,第一组是_
,第二组是_
,第三组是non
。
但是,我无法理解字符串_
,_
和_non
如何与第二组匹配,前提是__
引用了\1
最终会在_
开始时期望_
的表达式。
答案 0 :(得分:5)
模式: ^\s*(_?)(\S+?)\1\s*$
总体而言,这种模式:
^
从字符串的开头
\s*
匹配0个或更多空白字符
(_?)
匹配并捕获0或1下划线(捕获组1)
(\S+?)
非贪婪匹配并捕获1个或多个非空白字符(捕获组2)
\1
匹配捕获组1中匹配的内容
\s*
匹配0个或更多空白字符
$
匹配行/字符串
主题: _
第1组:
第2组:_
最初,这将在第一个捕获组中匹配。但随后引擎转移到第二个捕获组并且它期望至少有一个char匹配,因此引擎回溯并从第一个捕获组获取char,因为第一个捕获组中的?
使其成为可选的,并且_
是非空格字符。然后,由于捕获组1中最终没有匹配(因为必须满足组2),所以\1
后引用中没有任何内容可匹配。
主题: _non
第1组:
第2组:_non
最初,_
在第1组中匹配,然后在第2组中匹配non
。然后引擎会查找_
个\1
引用,并在那里是none,因此引擎回溯和匹配将其从组1中删除并在组2中匹配。
主题: _non_
第1组:_
第2组:non
与上一个类似:最初{1}在组1中匹配,然后{2}在组2中匹配。然后引擎为_
查找non
}引用,它匹配,因此第1组保持其_
,第2组只保留\1
。
主题: _
第1组:
第2组:non
这与第一个__
示例基本相同。最初,第一个__
在第1组中匹配。然后第2个_
在第2组中匹配。然后_
尝试匹配另一个_
,因为第1组有一个,但没有。但是第2组需要至少1个字符,但可以有更多,所以正则表达式引擎备份并将第1组的匹配放入第2组。
主题: \1
第1组:
第2组:
这导致不匹配。引擎开始将第一个_
放入组1,但是然后将空间放入组2中失败。因此它会备份并尝试将第一个_ _
放入组2.由于没有组1,也没有_
匹配。然后该空间由_
匹配,但随后匹配在最终\1
上失败,因为该模式在字符串结尾之前仅显示空格。
<强>旁注强>
您在评论中提到:
如果匹配第一个组的
\s*
,则必须与_
匹配_
。_
它是指表达式还是结果 表达
它引用表达式的结果(实际捕获的内容),而不是表达式本身。