Help with Regex Placeholder

Hi All

Hope there is someone who can help me out here.

I have an Rfid reader that output a string containing AsciII and HEX numbers.

Example string: 8100 10F826 4F

In this example the Rfid ID is: 10f826 which is what I want to extract with Regex.
The number is different for each Rfid tag I have, so therefore I need to extract placeholder 5 to 10.

Hope there is someone who can help me out here, as I’m stuck :frowning:

Best

Nanna

Context please? Do you have that whole message in a String Item, or are you trying to apply a transform in a mystery binding, or in a profile?

Hi @rossko57

yes i have it in a string item

String Rfid_receive "Rfid recieve [%s]" <settings> (gSet) { udp="<[10.0.0.26:*:'REGEX((.*))']" }									

With the above I get the complete readout of the Rfid tag : 810010F8264F, I need to extract only 10F826.

The value is different with each Rfid tag, but the placeholder 5-10 is always the same.

Because I have no idea about REGEX I’d do it an rule by splitting the string :wink:
(Where I could also ring bells for unexpected codes etc.)

Would there be any chance you could give me an example doing so?

I think this is a terrible way to do it, REGEX is probably better

logInfo("test", "raw " + Rfid_receive.state.toString)
val firstcut = Rfid_receive.state.toString.split("8100")
logInfo("test", "first " + firstcut.get(1))
val seccut = firstcut.get(1).split("4F")
logInfo("test", "second " + seccut.get(0))

But this does allow expansion if things are not as you expect

The problem is that the 8100 and 4F is not unique, they differ from each Rfid tag that are used.

I did a little reading but I am on my phone and it’s hard to debug.

Can you use
(.{9}).{8}(.{4}).
If I read correct this may select certain characters from string. Like I said I can’t test it was an example I found.

Also more information: http://www.regexlab.com/en/regref.htm
See section 2. My best guess
The concepts of “Lookbehind assertion” and “Lookahead assertion” are similar. “(?<=xxxxx)” and “(?<!xxxxx)” require the string on the left side of the gap to be able to match or to be not able to match the subpattern, not the right side. And they will not match any characters themselves too.

Example5: When pattern "(?<=\d{4})\d+(?=\d{4})" matches "[1234567890123456](tel:1234567890123456)", it will match 8 numbers in the middle, except first 4 numbers and last 4 numbers. Because

Is the string always exactly the same pattern?

CCCC CCCCCC CC

Four characters, a space, six characters, a space and then two characters.

If so something like the following should work:

\w{4}\s(\w{6})\s\w{2}

\w means “word character” so should match numbers and letters but not special characters or white space. {x} means “match the previous x times”. \s means white space.

The stuff in parens is what get’s returned (the six characters after the first four characters).

In openHAB, you must match all of the String and tell it what part you want with the parens. This is different from “standard” regex and is largely why we see “It works on regex101.com but not in openHAB”.

OK, so there are not spaces in the String than. No problem, just remove the \s from the above.

Depending on what you are doing with these, Design Pattern: Encoding and Accessing Values in Rules Approach 3 might be useful to you.

2 Likes

Hi @rlkoshak

I have tried your Regex on regex101.com and it gives me the result I want :slight_smile:

I have tried to to do the conversion in this rule:

rule "Convert String to Item Number"
  when
    Item Tex_UDP_Send received update
 then
    // use the transformation service to retrieve the value
    val newValue = transform("REGEX", ".*=(w{4}(w{6})w{2}).*", Rfid_recieve.state.toString)

    // post the new value to the Number Item
    Rfid_receive_num.postUpdate( newValue )
 end

I have no error in Karaf, but I don’t get any output - do you have any idea what I do wrong?

After Openhab restart I do get this warning

19:21:19.125 [WARN ] [arthome.model.script.actions.BusEvent] - Cannot convert 'null' to a state type which item 'Rfid_receive_num' accepts: [DecimalType, QuantityType, UnDefType].

Come on, you know how to use logInfo() to get before and after values to pin down where the issue is.

EDIT - I figured there must be a stringy way to do this, where you have known character counts. Homework results -


var fred = "abcd123456xy"
var mary = fred.substring(4,10)  // from position, to position, where example a=0 and x=10
logInfo ("test", "result " + mary)   // shows 123456
2 Likes

Thanks a lot everyone for your help

I finally got it solved - the easy way for me, was to use the substring method.

Best Nanna

1 Like