ChatGPT解决这个技术问题 Extra ChatGPT

How to use regex in XPath "contains" function

I would like to match the following text sometext12345_text using the below regex.

I'm using this in one of my selenium tests.

String expr = "//*[contains(@id, 'sometext[0-9]+_text')]";
driver.findElement(By.xpath(expr));

It doesn't seem to work though. Can somebody help?

What version of XPath are you using?
What made you think it might work? Were you just guessing, or did you find misleading information somewhere?
@MichaelKay, I guessed that it might support. As per this, (w3.org/TR/xquery-operators/#string.match) it may not. Thanks.

R
Robin

XPath 1.0 doesn't handle regex natively, you could try something like

//*[starts-with(@id, 'sometext') and ends-with(@id, '_text')]

(as pointed out by paul t, //*[boolean(number(substring-before(substring-after(@id, "sometext"), "_text")))] could be used to perform the same check your original regex does, if you need to check for middle digits as well)

In XPath 2.0, try

//*[matches(@id, 'sometext\d+_text')]

This seems to work: //*[boolean(number(substring-before(substring-after(@id, "sometext"), "_text")))], but it's highly specific to this use case
Yup, regex support would obviously be stronger/more flexible. Nice trick though!
seems like 'ends-with()' comes only with XPath2/XQuery but not with XPath1.0, proofs: w3.org/TR/xpath/#section-String-Functions , w3.org/TR/xpath-functions/#func-ends-with
How do I get to know which version of xpath is bein used in my selenium test?
couldn't use ends-with in xpath 1.0, but starts-with works perfectly :)
H
Harish Kiran

In Robins's answer ends-with is not supported in xpath 1.0 too.. Only starts-with is supported... So if your condition is not very specific..You can Use like this which worked for me

//*[starts-with(@id,'sometext') and contains(@name,'_text')]`\

p
paul trmbrth

If you're using Selenium with Firefox you should be able to use EXSLT extensions, and regexp:test()

Does this work for you?

String expr = "//*[regexp:test(@id, 'sometext[0-9]+_text')]";
driver.findElement(By.xpath(expr));

I'm using webdriver(2.39.0) with firefox(26.0). I tried the above suggestion but it results in error. InvalidSelectorError: Unable to locate an element with the xpath expression //*[regexp:test(@id, 'sometext[0-9]+_text')] because of the following error: [Exception... "An attempt was made to create or change an object in a way which is incorrect with regard to namespaces" code: "14" nsresult: "0x8053000e (NamespaceError)" location: "<unknown>"] Thanks for helping.
I'm not familiar with Selenium, but if you find a way to register the namespace "http://exslt.org/regular-expressions" under the "regexp" prefix, it could work
Looks like the issue is still open for registering namespaces (code.google.com/p/selenium/issues/detail?id=1694), and it's independent of the EXSLT extensions. There are signs of people doing it here stackoverflow.com/a/19130149/2572383 ... Ah no, I think the parsing there is done outside
@paultrmbrth - - could you please help me with a related question ? stackoverflow.com/questions/44292671/…