我原本一直以为,在参数设置得当时,两者的匹配顺序是一样的。但是最近,我遇到了这个例子:
Cases[2 a b, a b :> j, All](* All这语法文档里没写,它等效于{0,Infinity} *)
(* {} *)
(* 以防万一我们用{0,Infinity}再试下: *)
Cases[2 a b, a b :> j, {0, \[Infinity]}]
(*{}*)
ReplaceAll是没问题的:
2 a b /. a b -> j
(* 2 j *)
SE帖子《Successful match in Replace but not in Cases?》(编号5002)尝试对此做了探索,结论是,尽管Cases会考虑Flat属性,但它不会进行越级检查,说具体点就是:
2 a b 完整形式 Times[2, a, b],因为有Flat属性,它可以等效于
Times[2, Times[a, b]]
因此形如
Cases[2 a b, 2 _ :> i, All]
的匹配可以生效。(Cases在第0层识别出了 Times[2, _]结构。)
但是,Cases在此层次的检查又只限于该层。对于Times[2, Times[a, b]],此时 Times[a, b] 位于第1层,所以Cases查不到它(ReplaceAll的行为则不同,它会顺带检查变换出的所有层),等到Cases开查第一层,Times又已经“成了过去”,Cases此时只能查到2, a, b(这个行为倒是很正常),因此最终输出空表——当然了,这套解释目前没有官方背书,因此可能有误,大家可以进一步探索。
Cases[2 a b, a b :> j, All](* All这语法文档里没写,它等效于{0,Infinity} *)
(* {} *)
(* 以防万一我们用{0,Infinity}再试下: *)
Cases[2 a b, a b :> j, {0, \[Infinity]}]
(*{}*)
ReplaceAll是没问题的:
2 a b /. a b -> j
(* 2 j *)
SE帖子《Successful match in Replace but not in Cases?》(编号5002)尝试对此做了探索,结论是,尽管Cases会考虑Flat属性,但它不会进行越级检查,说具体点就是:
2 a b 完整形式 Times[2, a, b],因为有Flat属性,它可以等效于
Times[2, Times[a, b]]
因此形如
Cases[2 a b, 2 _ :> i, All]
的匹配可以生效。(Cases在第0层识别出了 Times[2, _]结构。)
但是,Cases在此层次的检查又只限于该层。对于Times[2, Times[a, b]],此时 Times[a, b] 位于第1层,所以Cases查不到它(ReplaceAll的行为则不同,它会顺带检查变换出的所有层),等到Cases开查第一层,Times又已经“成了过去”,Cases此时只能查到2, a, b(这个行为倒是很正常),因此最终输出空表——当然了,这套解释目前没有官方背书,因此可能有误,大家可以进一步探索。