user5334993
user5334993

Reputation: 63

XQuery negate regex

Im searching for a way to negate a regular expression in xquery. Using Oracle with the XMLQuery function.

Ill give an example first:

XMLQuery(
    'for $number in ("2a2", "32", "1234", "12", "32a3", "")
    where ora:matches($number,"^[0-9]{4}$")

    return xs:integer($number)'
    passing xml RETURNING CONTENT
    )

this works perfect except one thing. I want to get the exact opposite of entries which do not match the pattern.

I tried

where fn:not(ora:matches($number,"^[0-9]{4}$"))
where ora:matches($number,"^[0-9]{4}$") = false()
where ora:matches($number,"^[0-9]{4}$") = fn:false()

which all give me this

ORA-01722: Ungültige Zahl 01722. 00000 - "invalid number" *Cause: The specified number was invalid. *Action: Specify a valid number.

Upvotes: 3

Views: 656

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243469

Just use this pure XPath 2.0 expression (XPath 2.0 is a proper subset of XQuery):

("2a2", "32", "1234", "12", "32a3", "12345", "")
                      [not(matches(., "^[0-9]{4}$"))]

When this expression is evaluated (in XQuery, XSLT 2+ or any standalone XPath/XQuery interpreter tool), the wanted, correct result is produced:

2a2 32 12 32a3 12345

One can further simplify this:

("2a2", "32", "1234", "12", "32a3", "12345", "")
                      [not(matches(., "^\d{4}$"))]

Upvotes: 2

Markus Jarderot
Markus Jarderot

Reputation: 89171

The negation of ^[0-9]{4}$ could be written as ^[0-9]{0,3}$|^[0-9]{0,3}[^0-9]|^[0-9]{4}.

  • ^[0-9]{0,3}$ will match a number that is too short.
  • ^[0-9]{0,3}[^0-9] will match a string that contains a non-digit in the first four characters.
  • ^[0-9]{4}. will match a string that starts with four digits, but is too long.

Upvotes: 0

Related Questions