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);
テスト
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 は特に例外的なトークンが無くて思ったより簡単だったよ><!
正規表現は自信ないんで間違ってたら教えてください><!
追記
この正規表現にはいろいろと問題があったためこちらで書き直しました。
ごめんなさい><