Question Lewis Greitzer · Jul 9, 2018

Using regular expressions in a routing rule

I would like to examine the contents of my OBX-5 field and not route the message if it contains alphabetic characters. I've tried various combinations of the Match and Contains functions, with no luck. Should I be using the COS ? operator or plaini regular expressions?

e.g.

OBX-5 Contains "\D"

OBX-5 Contains "?.A"

OBX-5 Contains "[A-Z]"

Comments

Jeffrey Drumm · Jul 9, 2018

If  you expect to be using regular expressions frequently, it might be worth your while to write a classmethod that extends Ens.Rule.FunctionSet and wraps $MATCH or $LOCATE in something that can be called from a business rule (or DTL for that matter).

/// Custom methods for business rules and DTLs
Class User.Rule.FunctionSet Extends Ens.Rule.FunctionSet
{
/// Accepts a string <var>pString</var> and regular expression pattern <var>pPattern</var>
/// as arguments; returns 0 for no match, and a positive integer indicating the match's
/// position if there is a match.
ClassMethod REMatch(pString As %String, pPattern As %String) As %Integer
  {
              Return $LOCATE(pString,pPattern)
  }
}

You could use $MATCH instead of $LOCATE in the method above, but $MATCH() assumes the supplied pattern is begin- and end-anchored. In other words, $LOCATE("this","is") returns the positive integer 3, which for all Cache boolean purposes evaluates as true. $MATCH("this","is") returns 0 (false) since "^is$" does not match "this".

If the class you create extends Ens.Rule.FunctionSet and resides in your production's namespace, it will be selectable from the function dropdown list in both the Business Rule and DTL expression editors.

0
Lewis Greitzer  Jul 10, 2018 to David Crawford

This is in a routing rule, so when I have:

when HL7.{OBXgrp(1).OBX:ObservationValue(1)} Matches "[a-z]"

and when I run a message through I get the following error:

  ERROR <Ens>ErrBPTerminated: Terminating BP iSirona_Proc2 # due to error: ERROR <Ens>ErrException: <SYNTAX>zMatches+1 ^Ens.Util.FunctionSet.1 -- logged as '-'
number - @'
Quit $S(""=$g(pattern):""=$g(value), 1:$g(value)?@$g(pattern)) }'
> ERROR <Ens>ErrException: <SYNTAX>zMatches+1 ^Ens.Util.FunctionSet.1 -- logged as '-'
number - @'
Quit $S(""=$g(pattern):""=$g(value), 1:$g(value)?@$g(pattern)) }'
0
Jeffrey Drumm  Jul 10, 2018 to Lewis Greitzer

the Matches method uses the ? (question mark) syntax for pattern matching, not regular expressions. I much prefer the latter ...

0
Lewis Greitzer  Jul 10, 2018 to Jeffrey Drumm

Any hints on the syntax? I've tried

HL7.{OBXgrp(1).OBX:ObservationValue(1)} Matches ?3N

HL7.{OBXgrp(1).OBX:ObservationValue(1)} Matches ?"-"

The following: HL7.{OBXgrp(1).OBX:ObservationValue(1)} Matches "?.A"

gives me the following error:

  ERROR <Ens>ErrBPTerminated: Terminating BP iSirona_Proc2 # due to error: ERROR <Ens>ErrException: <SYNTAX>zMatches+1 ^Ens.Util.FunctionSet.1 -- logged as '-'
number - @'
Quit $S(""=$g(pattern):""=$g(value), 1:$g(value)?@$g(pattern)) }'
> ERROR <Ens>ErrException: <SYNTAX>zMatches+1 ^Ens.Util.FunctionSet.1 -- logged as '-'
number - @'
Quit $S(""=$g(pattern):""=$g(value), 1:$g(value)?@$g(pattern)) }'
0
Jeffrey Drumm  Jan 15, 2021 to Lewis Greitzer

This question is more than 2 1/2 years old now, but I guess I missed it when it was posted. Regardless, the issue is that "?" is the match operator that "Matches" represents, and is not part of the pattern itself. Your match pattern should not include the "?" character.

0
David Crawford  Jul 10, 2018 to Lewis Greitzer

Oops! Sorry I forgot it was for a rule. Also edited for redundancy as I see there's more comments now. Does the visual expression editor give any indication of failure?

0
Lewis Greitzer  Jul 10, 2018 to David Crawford

The following attempts give me a syntax error "Error parsing expression"  when I save the rule:

HL7.{OBXgrp(1).OBX:ObservationValue(1)} Matches ?3N

HL7.{OBXgrp(1).OBX:ObservationValue(1)} Matches ?"-"

HL7.{OBXgrp(1).OBX:ObservationValue(1)}?"-"

HL7.{OBXgrp(1).OBX:ObservationValue(1)} ?"-"

0
David Crawford  Jul 10, 2018 to Lewis Greitzer

Are you wrapping your expression in quotes? This indicates that Matches only accepts strings as the pattern. If that doesn't work I'm really not sure what the issue is, and I would try to pass your values to a custom function where you can examine what's really going on, and see if you can replicate the problem. This is essentially what Jeffrey Drumm was suggesting.

0
David Crawford · Jul 10, 2018

What do you mean you're not having luck? For example, what happens when you call on the $match or $locate functions on your field? I can make regex on your three examples without issue for simple strings, like below which works:

$locate("123dsd534","[a-z]")

0
Aaron Vail  Feb 6, 2020 to Aaron Vail

Nevermind.  Ugh. Been a rough week.

HL7.{PID.7} Contains CurrentDateTime("YYYYMMDD")

0
Jeffrey Drumm  Feb 7, 2020 to Aaron Vail

As a general rule, I'd suggest using the StartsWith() function in the DTL wizard when comparing date fields. In your case, the Birthdate field very likely does not include a Time component at a resolution of seconds. If it did, though, you could run into many combinations where the date value from CurrentDateTIme() would match.

For example, Contains() would return true on the 19th or 20th of February 2020 against "20200220200219" ... February 20th 2020 at 8:02:19pm. This would certainly be a rare occurrence, but not impossible.

0
Jeffrey Drumm  Jan 15, 2021 to Aaron Vail

Nevermind.  Ugh. Been a rough week.

HL7.{PID.7} Contains CurrentDateTime("YYYYMMDD")

Close, but not quite:

0
Jeffrey Drumm · Jul 10, 2018

If you're really set on using the ? notation for pattern matching, see the "ObjectScript Pattern Matching" section of the documentation. In the pattern field of the Match function in the expression editor, you would enter the pattern without a leading question mark. For example, you can use the string ".A" to match any number of upper or lowercase characters, or ".AP" to match any number of upper/lowercase and punctuation characters.

0
Aaron Vail · Feb 6, 2020

 I have a similar issue.  I'm trying to look for kids born "today" for Newborn Screening.  I've built a previous Rule Condition that looks a field in a Record Map and does a look up.  If the record map field is not found in the list then the record is skipped.

But how do I code the condition to look at the PID.7 and if that is "today" Send it along?? I can get the field value.  It's the "get today's date" I'm having trouble with.

I have this much so far "HL7.{PID.7}Contains"   smiley

0
Barry Veach · Jan 14, 2021

I have a routing rule that uses Matches e.g. Matches "1P4N1P1A5N1A1P" that matches against this string <0508:F00002R>

How do I include literals within the expression editor?

Pattern match doc indicates something like this 1P4N":F"5N"R"1P

Since within the expression is surrounded by double-quotes, that breaks the syntax in the editor.

Have tried many variations, none of which work.

0
Jeffrey Drumm  Jan 14, 2021 to Barry Veach

Your syntax for the match argument is wrong. You need quantifiers for the literal strings: 1P4N1":F"5N1"R"1P. This is not obvious from the documentation ... I only discovered it through experimentation.

It appears as though the expression editor expects the pattern to be a quoted string, so you'll probably need to follow the syntax for quoting strings that contain quote characters: "1P4N1"":F""5N1""R""1P"

0
Barry Veach  Jan 17, 2021 to Jeffrey Drumm

Correct. Adding the qualifiers and using double-quotes did the trick

For string: 0508:F00002R this works "4N1"":F""5N1""R""" 

For string: 0508:CX00002R this works "4N1"":CX""5N1""R"""

Thanks!

0