XPath, CSSSelectorで、DOMをクエリする場合に、クラス名やコンテンツの文字列で検索したい場合が多い。
// xpath
document.evaluate('//dom[ contains(@class, "abc") ]', this, null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
// css-selector
document.querySelector('a[class*="abc"]');
単純なクエリでは問題ないが、正規表現が使えると、圧倒的にクエリの表現力が上がる。
rexpath
を使うと、XPath, CSSSelectorと正規表現を協調させられる。
/* classが /tr-item\d+_.+/i にマッチする aタグ を取り出す */
// xpath
document.rexpath(['and', '//a', ['@~', 'class', /tr-item\d+_.+/i]]);
// switch to use css-selector
rexpath.use_css_selector();
// css-slector
document.rexpath(['and', 'a', ['@~', 'class', /tr-item\d+_.+/i]]);
やるべきことは手短に
独自のクエリ言語を開発するとか、XPath2.0をwebアセンブリで実現するとか、
まあいろいろやり方があるんだろうけれど。
極力省エネで、合理的に、直交する解決策を考えて実装した。
まあそこそこ便利だったので、記しておく。
どうするか
拙作のnpmライブラリ、rexpath を使う。
既存のXPath, CSSSelector, RegExp を薄くラップしたクエリ言語を定義することで、
最小限のエネルギーでDOMクエリと正規表現を協調させることができる。
クエリを継続渡し
形式のクロージャにコンパイルすることでバックトラック探索を実現している。
特別なレクサはない。JavaScriptの配列を基本として簡単なクエリ言語を実現している。
Hello World
chrome devtools consoleなどで、
// jump to qiita
document.location.href = "https://qiita.com";
// unpkgからrexpathをロードする。
var element_script = document.createElement('script');
element_script.src = 'https://unpkg.com/rexpath';
document.head.appendChild(element_script);
// テキトーな例。 class属性が正規表現 /tr-item_.+/i にマッチするaタグを見つけ出して削除する。
var links = document.rexpath_all(['and', '//a', ['@~', 'class', /tr-item_.+/i]]);
links.forEach(link=>link.parentElement.removeChild(link));
詳細
文法、例など、まだ未整備だが書いてある。
README.md を参照のこと。