I'm using Json.Net's SelectToken method to query JSON using JSONPath with expressions like:
JToken acme = o.SelectToken("$.Manufacturers[?(@.Name == 'Acme Co')]");
-- http://www.newtonsoft.com/json/help/html/QueryJsonSelectTokenJsonPath.htm
Does JSONPath support XPath style String Functions?
By String Functions, I mean those described in How to use like in XPath?
For example, is there syntax for the contains()
method?
I've tried:
o.SelectToken("$.Manufacturers[?(contains(@.Name, 'Acme')]");
but JSON.Net complains of a syntax error (it doesn't like contains
).
Json.NET Release 11 introduced the regex operator =~
for JSONPath queries. Using it you can do string pattern matching including contains()
matches. For example:
To match a value containing the string Acme
use =~ /Acme/
:
o.SelectToken("$.Manufacturers[?(@.Name =~ /Acme/)]")
To match a value containing the word Acme
, bracket it with \b
:
o.SelectToken("$.Manufacturers[?(@.Name =~ /\\bAcme\\b/)]")
To do a case-insensitive match on a string containing acme
, preface the case-insensitive portion with (?i)
:
o.SelectToken("$.Manufacturers[?(@.Name =~ /(?i)acme/)]")
(?-i)
ends case-insensitive matching.
To match a value that does not contain Acme, use =~ /^(?!.*Acme).*$/)
:
o.SelectToken("$.Manufacturers[?(@.Name =~ /^(?!.*Acme).*$/)]")
See: C# Regex to match a string that doesn't contain a certain string?.
To match strings starting with Acme
, insert ^
at the beginning of the regex:
o.SelectToken("$.Manufacturers[?(@.Name =~ /^Acme/)]")
To match strings ending with Acme
, add $
at the end of the regex:
o.SelectToken("$.Manufacturers[?(@.Name =~ /Acme$/)]")
To match strings with a specified length N
, use =~ /(?s)^.{N}$/)
:
o.SelectToken("$.Manufacturers[?(@.Name =~ /(?s)^.{7}$/)]")
Here (?s)
specifies single line mode (which forces newlines to be included in the character count), .
matches any character, the quantifier .{7}
requires exactly 7 matches of the preceding token .
, and ^
and $
match the beginning and end of the string (which prevents the regex from matching strings longer than 7 characters).
Demo fiddle here.