Question
· Nov 6, 2020

Piece or String function using Matches [A-Z]

I am trying to match on config items that have the same Vendor name in them for custom alerting.

Example:

FromVendornameSiteADT

ToVendornameORM

Where Vendorname could be several systems that have multiple interfaces.

How can I find all config items (interface names) with the same Vendor name, without explicitly naming them?

I was trying to use $Piece to segment out the CamelCase pieces (as the name I want is always the 2nd Capitalized section), but could not find a way to integrate match regex logic (e.g. [A-Z]) inside $Piece or other String extract functions.

Discussion (9)3
Log in or sign up to continue

Hi Brian,

Could you please with below code.

----------------------------------------------------

Class Sample.TempUtil Extends %RegisteredObject
{

ClassMethod GetSecondUpperCase(pInput As %String) As %String
{
 ;w ##class(Sample.TempUtil).GetSecondUpperCase("GetSecondUpperCase")
 SET stsrtpos=$LOCATE(pInput,"[[:upper:]]{1}",2)
 SET endpos=$LOCATE(pInput,"[[:upper:]]{1}",(stsrtpos+1))
 SET result=$EXTRACT(pInput,stsrtpos,(endpos-1))
 
 quit result
}

}
----------------------------------------------------------------

Regards,

Muni Ganesh

Have a look at %Regex.Matcher. Since you always want the 2nd capitalized section you can just make that your regex capture group:

    set matcher=##class(%Regex.Matcher).%New("^[A-Z][a-z]*([A-Z][a-z]*)")                             
    set matcher.Text="ToVendornameORM"
    if matcher.Locate() {
        write "Found ",matcher.Group(1)," at position ",matcher.Start,!
    }

This gives me the output:

Found Vendorname at position 1

Here's the code to get capitalized piece of string by number:

/// Get Capitalized piece.
///   str - string to search
///   piece - 1-based piece to return
/// write ##class(test.CustomQuery).GetCapitalizedPiece()
ClassMethod GetCapitalizedPiece(str As %String = "lowerHelloWorldAgainHelloWorldAgainHelloWorldAgainHelloWorldAgain", piece As %Integer = 1) As %String
{
    
    // Only uppercase letters
    set upper = $tr(str, $zcvt(str, "l"))
    
    // Number of uppercase letteres
    set capCount = $l(upper)
    
    // Quit if requested piece can not exist
    quit:piece>capCount ""
    quit:piece<1 ""
    
    // First letter in our capitalized piece
    set startLetter = $e(upper, piece)
    
    // All previous capitalized letters
    set prevLetters = $e(upper, 1, piece - 1)

    // Check if current capitalized letter is a first capitalized letter
    // If not - skip previous capitalized letters
    if '$find(prevLetters, startLetter) {
        set start = $find(str, startLetter) - 1
    } else {
        set count = $l(prevLetters, startLetter) + 1
        set start = 0
        while $i(count,-1) {
            set start = $find(str, startLetter, start)
        }
        set start = start - 1
    }
    
    // Is this capitalized piece the last one?
    if piece=capCount {
        set end = $l(str)
    } else {
        set end = $find(str, $e(upper, piece + 1), start) - 2
    }

    quit $e(str, start, end)
}

Advantages over regexp:

  • ~50 times faster
  • Get any piece, not only the second one (although generating required regexp by piece number seems easy to do)