[SOLVED] Weird replaceAll behaviour (!?)

Tags: #<Tag:0x00007f6184545960>

Again I struggled with string handling and I just wanted to share in case someone encounters the same issue.

Like with REGEX I am always spending significant amount of time to find a solution for a seemingly easy problem.

I extract numbers from a file like 130,45 (please note the comma as the typical decimal character in Germany).
To transfer this to a number I use the string and replace the “,” with a period “.”.
The example below works fine - So far so good:
var Number costs= new DecimalType()
costs= strng.replaceAll(",",".") // changing the comma to a period

In the file there are sometimes higher numbers like 1.505,52 (one thousand five hundred something)
To transfer this string into a DecimalType I tried the same like above, but the other way around:

var String mny = ""    
mny = strng.replaceAll(".","") // removing the thousands period
costs= mny.replaceAll(",",".") // changing the comma to a period

Which does not work (the first replaceAll).
But his does with double escapes:

mny = strng.replaceAll("\\.","")

Maybe it’s obvious to “real” SW developers - for me it’s not :wink:

That is, because . is the regex “any character” wildcard.

2 Likes

Thanks, Udo.
So, the replaceAll stuff works with the same stuff like REGEX.
-> lesson learned. :wink:
Still I struggle often with a mismatch between REGEX101.com and the REGEX in OH.
I know that this is related to my lack of experience not being able to compensate this mismatch.

Two examples:
1.
"05.09.2019";"05.09.2019";"Vorname";"Name";"Strasse";"PLZ / Ort";"Tel. Nummer";"xxx";"yyy";"zzz";"0815";

With a REGEX transformation like ".?; I get the desired result on REGEX101 (using it without the global flag \g).
But OH seems to work globally always (no option to switch off \g) - at least i did not find information how to do it.

Another one is a newline.
I never made it work to stop as soon as a newline is found:
.*InputCH2=(.+)\n
This should drop everything after the newline from my expectation (and REGEX101.com), but returns also all the stuff in the upcoming lines of:

InputCH1=OFF
InputCH2=ON
InputCH3=OFF
InputVCH1=OFF
...

Yes, openHAB REGEX is a bit special (as always…) and one thing is, it’s always global, so you have to start with .* and end with .* (if there is any text around). Another thing: If REGEX doesn’t match at all, it will return the whole string.
n question of the multi line issue, you definitely have to add a .* after \n:

REGEX(.*InputCH2=(.+)\n.*)

otherwise \n will match to the last newline… :wink:

I tried that in my hours of testing.
Unfortunately that does not work and drives me crazy:

2020-06-30 19:02:11.290 [ERROR] [el.item.internal.GenericItemProvider] - Binding configuration of type 'http' of item 'Abus_http_1' could not be parsed correctly.
org.eclipse.smarthome.model.item.BindingConfigParseException: bindingConfig '<[cacheAbusState:10000:REGEX(.*InputCH2=(.+)
.*' doesn't contain a valid binding configuration

and with \n it’s the same error:
.*InputCH2=(.+)\\n.*

Binding configuration of type 'http' of item 'Abus_http_1' could not be parsed correctly.
org.eclipse.smarthome.model.item.BindingConfigParseException: bindingConfig '<[cacheAbusState:10000:REGEX(.*InputCH2=(.+)\n.*' doesn't contain a valid binding configuration

missing bracket?

Right :wink:

But still not the desired result:
{http="<[cacheAbusState:10000:REGEX(.*InputCH2=(.+)\\n.*)]"}

leads to

OFF
InputCH3=OFF
InputVCH1=OFF
InputVCH2=DEACTIVATED
InputVCH3=DEACTIVATED
OutputCH1=OFF
OutputCH2=OFF
OutputWired=OFF
AlarmPowerFail=OFF
AlarmLowBattery=OFF
AlarmFault=OFF
AlarmFire=OFF
AlarmTechnical=OFF
AlarmBurglary=OFF
AlarmEntry=OFF

and with your original suggestion:
{http="<[cacheAbusState:10000:REGEX(.*InputCH2=(.+)\n.*)]"}
this leads to:

Binding configuration of type 'http' of item 'Abus_http_1' could not be parsed correctly.
org.eclipse.smarthome.model.item.BindingConfigParseException: bindingConfig '<[cacheAbusState:10000:REGEX(.*InputCH2=(.+)
.*)]' doesn't contain a valid binding configuration

But never mind and thanks for your help.
I have found a dirty but working solution:
{http="<[cacheAbusState:10000:REGEX(.*InputCH2=(.*)\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*\\n.*)]"}

Well, it would be easier to do it this way:

{http="<[cacheAbusState:10000:REGEX(.*InputCH2=(.+)\\nInputCH3.*)]"}

Thanks for your patience
I tried that as well in the past, because I expected this to work, too.
But it does not:

2020-07-01 11:35:55.409 [INFO ] [pse.smarthome.model.script.+++ DEBUG] - +++ Abus_http_1 ON
InputCH3=ON
InputVCH1=OFF
InputVCH2=DEACTIVATED
InputVCH3=DEACTIVATED
OutputCH1=OFF
OutputCH2=OFF
OutputWired=OFF
AlarmPowerFail=OFF
AlarmLowBattery=OFF
AlarmFault=OFF
AlarmFire=OFF
AlarmTechnical=OFF
AlarmBurglary=OFF
AlarmEntry=OFF

Because my approach above works with multiple “\\n”, I guess it must be really a newline between each line.
So, that’s the thing I struggle since quite some time.