@@ -86,19 +86,23 @@ public static function cssToXpath($path)
8686 return implode ('| ' , $ expressions );
8787 }
8888
89+ do {
90+ $ placeholder = '{ ' . uniqid (mt_rand (), true ) . '} ' ;
91+ } while (strpos ($ path , $ placeholder ) !== false );
92+
8993 // Arbitrary attribute value contains whitespace
9094 $ path = preg_replace_callback (
91- '/\[\S+?([ \'"])((?:(? !\1)[^ \\ \] | \\.)* )\1\]/ ' ,
92- function ($ matches ) {
93- return str_replace ($ matches [2 ], preg_replace ('/\s+/ ' , ' \s ' , $ matches [2 ]), $ matches [0 ]);
95+ '/\[\S+?([ \'"])((?!\1| \\\1).*? )\1\]/ ' ,
96+ function ($ matches ) use ( $ placeholder ) {
97+ return str_replace ($ matches [2 ], preg_replace ('/\s+/ ' , $ placeholder , $ matches [2 ]), $ matches [0 ]);
9498 },
9599 $ path
96100 );
97101
98102 $ paths = ['// ' ];
99103 $ path = preg_replace ('|\s+>\s+| ' , '> ' , $ path );
100104 $ segments = preg_split ('/\s+/ ' , $ path );
101- $ segments = str_replace (' \s ' , ' ' , $ segments );
105+ $ segments = str_replace ($ placeholder , ' ' , $ segments );
102106
103107 foreach ($ segments as $ key => $ segment ) {
104108 $ pathSegment = static ::_tokenize ($ segment );
@@ -147,7 +151,7 @@ protected static function _tokenize($expression)
147151
148152 // arbitrary attribute strict equality
149153 $ expression = preg_replace_callback (
150- '/\[@?([a-z0-9_-]+)=([ \'"])((?:(? !\2)[^ \\ \] | \\.)* )\2\]/i ' ,
154+ '/\[@?([a-z0-9_-]+)=([ \'"])((?!\2| \\\2).*? )\2\]/i ' ,
151155 function ($ matches ) {
152156 return sprintf ("[@%s='%s'] " , strtolower ($ matches [1 ]), str_replace ("' " , "\\' " , $ matches [3 ]));
153157 },
@@ -156,7 +160,7 @@ function ($matches) {
156160
157161 // arbitrary attribute contains full word
158162 $ expression = preg_replace_callback (
159- '/\[([a-z0-9_-]+)~=([ \'"])((?:(? !\2)[^ \\ \] | \\.)* )\2\]/i ' ,
163+ '/\[([a-z0-9_-]+)~=([ \'"])((?!\2| \\\2).*? )\2\]/i ' ,
160164 function ($ matches ) {
161165 return "[contains(concat(' ', normalize-space(@ " . strtolower ($ matches [1 ]) . "), ' '), ' "
162166 . $ matches [3 ] . " ')] " ;
@@ -166,7 +170,7 @@ function ($matches) {
166170
167171 // arbitrary attribute contains specified content
168172 $ expression = preg_replace_callback (
169- '/\[([a-z0-9_-]+)\*=([ \'"])((?:(? !\2)[^ \\ \] | \\.)* )\2\]/i ' ,
173+ '/\[([a-z0-9_-]+)\*=([ \'"])((?!\2| \\\2).*? )\2\]/i ' ,
170174 function ($ matches ) {
171175 return "[contains(@ " . strtolower ($ matches [1 ]) . ", ' "
172176 . $ matches [3 ] . "')] " ;
0 commit comments