REGEX problem - convert ["1234.56"] into Number

Hi friends,
I am going crazy with REGEX. I get a number back from my weather station via HTTP binding:

String testdaten  "Testdaten [%s mB]" <rain> {http="<[http://139.59.206.133:8080/[TOKEN]/get/v6:5000:REGEX((.*))]"}

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.

Thanks a ton,
mroggi

There was a posting related to this yesterday:

Thanks Thom!

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!

Can somebody help, please?

Also tried:

var String jsona1 = transform("REGEX", "[0-9.]", jsona)

But get a NULL

Out of the cold I can’t help with an example but “doesn’t contain a group” seems clear to me. You need to define a regex (group).

See here: http://docs.openhab.org/addons/transformations/regex/readme.html

Thom, I have seen this but could not make sense of it. Could you pls help me with the concrete case to get it to run?

My guess would be

REGEX(\[\"(.*)\"\])

See here for explanation: http://www.regexr.com/3fj24

Alternatively instead matching the “outside” you can match the “inside”:

REGEX(.*(\d+.\d+).*)

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.

Regex can be an art unto itself!

1 Like

Thanks for extending my short answer!

Thanks a lot guys, this is a great forum and sorry for my delay, I was away for work.

I have tried to use your advise to develop a rule:

rule "Get Hum"
    when 
        //Item TestSwitch changed to ON 
        Time cron "0 * * * * ?"
    then    {   
        val String json = sendHttpGetRequest("http://139.59.206.133:8080/eeeca3f38cf54991a48301a7e97de848/get/v6")
        val String json1 = transform("REGEX", "\[\"(.*)\"\]", json) 
                
        logInfo("Humidity","************* Value: " + json )           
        logInfo("Humidity B","************* Value: " + json1 )
        testdaten.sendCommand(json1)
        }   
end

But I get the following error:

2017-03-23 18:58:50.053 [INFO ] [ipse.smarthome.model.script.Humidity] - ************* Value: [“1018.651”]
2017-03-23 18:58:50.060 [INFO ] [se.smarthome.model.script.Humidity B] - ************* Value: null

Slowly I get the impression that REGEX is not working. Could you help me what is wrong???

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 :smiley: 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) 

WOW, THAT WORKS! Thanks a ton. I would have never figured that out by myself!!!