This gives my a string in the format [“1234.56”]. I want to use REGEX to extract only the number. I have tried REGEX((.?([0-9]?)%.?)) and REGEX ((["?.[0-9]?]")) but nothing works. I do not get back anything.
Can somebody please help me? I am going crazy and already spent hours without success.
I have created a rule, but not sure how I need to use the REGEX in a transformation. I did:
var String output = transform("REGEX", ".*", json)
but I get an error from this:
2017-03-22 16:51:01.023 [INFO ] [.internal.RegExTransformationService] - the given regular expression ‘^.*$’ doesn’t contain a group. No content will be extracted and returned!
The “group” concept is that a regex “captures” what it matches. While some applications only care that the regex matched at all, or perhaps what it matched, many times it is valuable to use the regex to ensure that you’re in the right “context” and only select a portion of the result.
In @ThomDietrich’s example, REGEX(.*(\d+.\d+).*)
it says, effectively, “only ‘remember’ the portion consisting of the digits and the decimal point between them” because of the parenthesis in the regex.
An example of where this might be important is consider the case where you’re trying to extract the second number out of
Temperature: 25.6 Humidity: 53.9 Pressure: 1103.7
You might do this by writing your regex as
Humidity: (\d+\.?\d*)
so you get the “right” number out of it, but don’t want Humidity: to be part of what’s returned.
Regex can be difficult sometimes, especially as it is implemented differently just about everywhere. I seldom get them right the first time, or even the tenth time. Some variants are “greedy” in matching (take as much as possible), some can effectively work from the back of the string and only work from the front, some support + (one or more) and others only support * (zero or more), some consider ( and ) as grouping characters,…
A regex checker can help, once you know the context. I’m guessing that openHAB uses Java-style regex when you find a checker you like.
As @jeffsf said building regex expressions for a specific system and in a specific environment is always tricky. Here’s what I’ve done. I’ve added your rule to my system and reduced the Regex to:
val String json1 = transform("REGEX", "(.*)", json)
The whole string is returned. Let’s get rid of the two characters to the left and the right:
val String json1 = transform("REGEX", "..(.*)..", json)
That also worked, however just matching “any character” (the dot) is not a good idea because this could easily match unexpected returns. So let’s match the brackets. This seems to be the part where my solution above was not right. Escaping the [ once doesn’t seem to be enough (A [ has a special meaning in regex and hence needs to be escaped). The error I’m seeing is “Error during the execution of rule Get Hum: Unclosed character class near index 7” -> Sounds like the character is not yet escaped in regards to the regex function.
That’s a common problem with regex provided via strings. Escape sequences need to be passed to the regex function but will be evaluated earlier. You need to escape the escape sequence I get that this doesn’t seem obvious to someone working with something like this for the first time. Anyhow, here’s the working solution:
val String json1 = transform("REGEX", '\\[\\"(.*)\\"\\]', json)
As mentioned before it’s good practice to match as precisely as possible. Therefore my ideal solution would be:
val String json1 = transform("REGEX", '\\[\\"(\\d+\\.\\d+)\\"\\]', json)