Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

=?utf-8?B?5bi46KaL5Lq654K66Yyv6KqkOg==?= /\Afoo|bar\z/

1 view
Skip to first unread message

Kang-min Liu

unread,
Aug 16, 2022, 10:38:04 PM8/16/22
to

在不同的職場裡面都已經看過好幾次了。總是會有人用正規表示式:

$s =~ /\Afoo|bar\z/

... 來意圖檢查 $s 是否為 "foo" 或 "bar"。

但是這正規表示式能比對到字串不只兩個,而是無限多個。

正規表示式:

\Afoo|bar\z

代表的是「所有以 foo 開頭的字串」與「所有以 bar 結尾的字串」兩集合的交集。
而不是 {"foo","bar"} 這個只有兩個字串的集合。

要滿足原意圖,必須補上小括號,但不要把 \A 與 \z 括入:

$s =~ /\A(foo|bar)\z/

一般來說我認為,若用了 | ,就要同時加上小括號來明確區分出範圍,不然很容易造成誤讀。

如果是明確寫成:

$s =~ /(\Afoo|bar\z)/

... 也可真正顯示出作者意圖真的就是要測試 $s 是否是「以 foo 開頭的字串」
或是「以 bar 結尾的字串」。

附帶一提,以測試 $s 是否等於某些特定值來說,改用 eq + any 來寫或許更能正
確地彰顯出作者意圖。

看是要用 List::Util 的 any:

use List::Util qw(any);

any { $s eq $_ } qw(foo bar)

或是 any Junction:

use Quantum::Superpositions qw(any);

$s eq any( qw(foo bar) )

都是不錯的,也不太容易不小心寫錯。

----
0 new messages