CSSセレクタとXPathの判別

Web::Scraperのjavascriptバージョンwebscraper.jsのとおりどっちとしてもvalidになるものがあるので、書くひとがどっちなのかを明示できるのが合理的だと思う。

そのうえでCSSセレクタを観察するとXPathでよく使われる / がセレクタの中で存在し得るのは E[foo="value"] のときだけなので / があるかどうかで判別すると簡潔に処理できる。
/ がなくてXPathCSSか誤判別する可能性があるとき、例として a という式の時にCSSだとコンテキストの子孫のa全部にマッチするけどXPathだとコンテキストの直接の子だけがマッチする。このときXPathであることを明示したければ ./ が自分自身をさすことを利用して ./a と書くことができる。つまり、どんなXPathも同じ意味のまま / を含んでいる形式で書き直すことができるので / の有無でCSSXPathかを判別すると、コードに変更を加えることなく書いている人が明示的にXPathであることを示せる。

'div[@class="t"]/me/a[@href="x"]'.replace(/".+?"/, "").match(/\//) // match
'E[class="t/s"]'.replace(/".+?"/, "").match(/\//) // null
        my $test = $exp;
        $test =~ s/".+?"//g;
        my $xpath = $test =~ m!/! ? $exp : HTML::Selector::XPath::selector_to_xpath($exp);