REGEX usage in xtend

Shame on me… I do not get it to put a REGEX expression into an xtend transform command.
I have a string which contains number and characters and I want to get the numbers only as 1 number

the required regex expression is [0-9]+
but any attempt to embed it into a transform command fails

	var String strCommand2 = transform("REGEX","[0-9]+",strCommand)

I have tried it with additional / ( and various combinations without luck.
Could somebody please help me out?

Even the example in our documentation does not work:
val newValue = transform("REGEX", ".*=(\\d*.\\d*).*", Temperature_str.state.toString)

You installed the REGEX transformation service? It is an optional add-on.

What error message do you get in your openhab.log, or what result do you get that is not what you expect?

Yes, I did

No error message.
If I print the value into log file
logInfo(fileName,"Regex value: {}",strCommand2)
it stays empty.
Log result: Regex value:

the closest I can get is with
var strCommand2 = transform("REGEX", ".*([0-9]).*", strCommand.toString())

that returns 3 if item state is 23p
cannot find a way to provide this global pattern flag g

really weird:
this

var strCommand2 = transform("REGEX", "(\\d+).*", strCommand.toString())

returns 23 when string is 23whatever.

However, this

var strCommand2 = transform("REGEX", ".*(\\d+)", strCommand.toString())

(note that .* is either left or right of regex group (\d+)
returns 3 when string is whatever23

.* on both sides of regex group does also not work

afaik REGEX will return the shortest possible match.

Hi Udo,
many thanks. You probably mean the implementation of regex in OH does not support that because the regex itself returns the desired value in any expression builder?

You can go to https://regex101.com/ and test your expression. It returns the same as that one build in OH.
To get back 23 from whatever23 you can use:

"[^0-9]+(\\d+)"

Hi Wolfgang,
my problem is not to find the correct regex expression. the problem is, to get it working in a DSL rule.
Your expression works on regex101.com, but not if you put it into a DSL rule.
And your expression only works if there are characters left from a number, (\d+) does not care even if there are characters left and right from a number.

With one exception. OH REGEX requires the pattern to match the entire string, including new lines and such. Then it will return only the first matching group (parens).

That trips of a lot of people.

@Oliver2, given the restrictions with the REGEX transform I’ve found the best way to construct the pattern is to find markers immediately before the string you want and markers immediately after the string you want and create a pattern along the lines of:

.*M(.*)N.*

where M is the marker before the string you want and N is the marker after the string you want.

So if your Item state follows the pattern of any number of digits followed by a letter, something like ([0-9]+)[a-zA-Z].* should do it. Note that the + is inside the parens.

Rich,
great that you help.
I have spent half a day and am desperate as I cannot get it working correctly.

Could you please show me the correct expression for my specific problem?
given string: charactersinfront1234charactersafter
expected result: 1234
amount of characters in front of numbers and after numbers can vary, also amount of number digits.

to say it in english: just get all numbers from that string.

many thanks in advance

.*([0-9]+).*

That would probably do it. It should return the first grouping of digits it encounters in the string.

However, if it’s not being greedy you might need to differentiate between the letters and the numbers.

[a-zA-Z]*([0-9]+)[a-zA-Z]*
1 Like

that returns the last digit only

VERY CLOSE! works, but does not cover special characters.

Anyway, MANY MANY thanks! Your suggestion was tearing down my mind blocker :slight_smile:

This is working now:

"\\D*(\\d+)\\D*"