IT戦記

プログラミング、起業などについて書いているプログラマーのブログです😚

XPath の字句解析をワンライナーで作ってみた。

ソースコード

var expression = '/html/body/div/[attribute::class="hoge fuga piyo"]';
var tokens = expression.match(/"[^"]*"|'[^']*'|\d+(?:\.\d*)?|\.\d+|\*|\/\/|\/|\||\+|!=|<=|>=|<|>|=|\(|\)|\[|\]|\.\.|\.|@|,|::|-|(?![0-9-:])[\w-]+:\*|\$(?:(?![0-9-:])[\w-]+:)?(?![0-9-:])[\w-]+|(?:(?![0-9-:])[\w-]+:)?(?![0-9-:])[\w-]+|\s+/g);

// tokens is ["/", "html", "/", "body", "/", "div", "/", "[", "attribute", "::", "class", "=", "\"hoge fuga piyo\"", "]"]

テスト

var reg = /"[^"]*"|'[^']*'|\d+(?:\.\d*)?|\.\d+|\*|\/\/|\/|\||\+|!=|<=|>=|<|>|=|\(|\)|\[|\]|\.\.|\.|@|,|::|-|(?![0-9-:])[\w-]+:\*|\$(?:(?![0-9-:])[\w-]+:)?(?![0-9-:])[\w-]+|(?:(?![0-9-:])[\w-]+:)?(?![0-9-:])[\w-]+|\s+/g;
console.log('//div/*'.match(reg));
console.log('/html//div/descendant-or-self::*'.match(reg));
console.log('div/@id/parent::*'.match(reg));
console.log('/html/*[following-sibling::div]'.match(reg));
console.log('//div/processing-instruction("php")'.match(reg));
console.log('//*[child::* and preceding::span]'.match(reg));
console.log('//*[((@class * @class + @title * @title) div (@class + @title)) > ((@class - @title) * (@class - @title))]'.match(reg));

まとめ

XPath は特に例外的なトークンが無くて思ったより簡単だったよ><!
正規表現は自信ないんで間違ってたら教えてください><!

追記

この正規表現にはいろいろと問題があったためこちらで書き直しました。
ごめんなさい><