3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

JSのDOMクエリ(XPath, CSSSelector)で、正規表現を使いたい

Last updated at Posted at 2020-04-08

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 を参照のこと。

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?