regexnotepad++regexp-replace

Move multiple captures to a string without duplicates using RegEx


I have made a RegEx procedure for my company, but have recently received a request for an enhancement to remove useless information.

I am editing programs in mass using RegEx on NotePad++

Currently, I create a list of numerics that have z at the end and throw it at the beginning of the code. I hope to use RegEx to capture the z numerics and throw them at the beginning of the code without duplicates, as this causes the program not to compile.

This is how I do the find of specific programs and replace in the array:

Find: (Object(?s:(?!Object).)*?ByteCode :)((?s:(?!Object).)*?(?:z =.*|.*z(?:,|\)).*)(?s:.*?)EndObject)

Replace: \1\nNumeric x, x, x, x, x\nNumeric x, x, x, x, x\2

Here is an edited example of what the code looks like before any numerics are added at the top using RegEx:

   Type : InfinityProgram
   LastChange : 2/18/2025 5:15:38 PM
   DeviceId : NetWork_MankatoO\OfcDmp\Vav5_26
   Alias : RmTempSignalPRG
   CreateTime : 2/18/2025 5:13:20 PM
   CreatedBy : Root\Acc
   TimeLocked : 2/18/2025 5:15:38 PM
   InstanceId : 7227/33
   ByteCode :
'ROOM TEMPERATURE CONTROL SIGNAL CALCULATIONS      ' Dylan Salisbury  Paape Energy Services     5/19/23

Numeric sync, lasthour
Numeric actn '     control loop "action" 1 or 0 (direct or reverse)

Line StartUp
  Goto RmHappy

Line RmHappy
  If ((IntrLkSystemRun = On) & (TempRmAvg > (StptRoom + 1)) & (TS > 2)) then Goto RmWarm
  TempRmCntrlSig = 50
  DamperPositionz = .5

Line RmWarm
  If ((IntrLkSystemRun = Off) or (TempRmAvg < StptRoom)) then Goto RmHappy
  TempRmCntrlSigz = PID11Fct(TempRmAvg, StptRoom, PIDTR[1], PIDTR[2], PIDTR[3], 0.5, actn, PIDTR[4], PIDTR[5], 0.5, 1, TempRmCntrlSigz, 0.005, Date)
  TempRmCntrlSig = (TempRmCntrlSigz * 100)
  DamperPositionz = .25

   EndByteCode
   Status : Active
  EndObject

Here is an edited example of what the code looks like now when I use my Numeric Array list:

   Type : InfinityProgram
   LastChange : 2/18/2025 5:15:38 PM
   DeviceId : NetWork_MankatoO\OfcDmp\Vav5_26
   Alias : RmTempSignalPRG
   CreateTime : 2/18/2025 5:13:20 PM
   CreatedBy : Root\Acc
   TimeLocked : 2/18/2025 5:15:38 PM
   InstanceId : 7227/33
   ByteCode :
Numeric ByPassDamperz, DamperPositionz, HeatingValvez, ModHumidiferz
Numeric RadValveMRz, TempRmCntrlSigz, ValvePositionz, VFDSpeedPump1z

'ROOM TEMPERATURE CONTROL SIGNAL CALCULATIONS      ' Dylan Salisbury  Paape Energy Services     5/19/23

Numeric sync, lasthour
Numeric actn '     control loop "action" 1 or 0 (direct or reverse)

Line StartUp
  Goto RmHappy

Line RmHappy
  If ((IntrLkSystemRun = On) & (TempRmAvg > (StptRoom + 1)) & (TS > 2)) then Goto RmWarm
  TempRmCntrlSig = 50
  DamperPositionz = .5

Line RmWarm
  If ((IntrLkSystemRun = Off) or (TempRmAvg < StptRoom)) then Goto RmHappy
  TempRmCntrlSigz = PID11Fct(TempRmAvg, StptRoom, PIDTR[1], PIDTR[2], PIDTR[3], 0.5, actn, PIDTR[4], PIDTR[5], 0.5, 1, TempRmCntrlSigz, 0.005, Date)
  TempRmCntrlSig = (TempRmCntrlSigz * 100)
  DamperPositionz = .25

   EndByteCode
   Status : Active
  EndObject

This is how I would like the code to look after one or more replaces from the original code snippet without numeric declaration:

   Type : InfinityProgram
   LastChange : 2/18/2025 5:15:38 PM
   DeviceId : NetWork_MankatoO\OfcDmp\Vav5_26
   Alias : RmTempSignalPRG
   CreateTime : 2/18/2025 5:13:20 PM
   CreatedBy : Root\Acc
   TimeLocked : 2/18/2025 5:15:38 PM
   InstanceId : 7227/33
   ByteCode :
Numeric TempRmCntrlSigz, DamperPositionz

'ROOM TEMPERATURE CONTROL SIGNAL CALCULATIONS      ' Dylan Salisbury  Paape Energy Services     5/19/23

Numeric sync, lasthour
Numeric actn '     control loop "action" 1 or 0 (direct or reverse)

Line StartUp
  Goto RmHappy

Line RmHappy
  If ((IntrLkSystemRun = On) & (TempRmAvg > (StptRoom + 1)) & (TS > 2)) then Goto RmWarm
  TempRmCntrlSig = 50
  DamperPositionz = .5

Line RmWarm
  If ((IntrLkSystemRun = Off) or (TempRmAvg < StptRoom)) then Goto RmHappy
  TempRmCntrlSigz = PID11Fct(TempRmAvg, StptRoom, PIDTR[1], PIDTR[2], PIDTR[3], 0.5, actn, PIDTR[4], PIDTR[5], 0.5, 1, TempRmCntrlSigz, 0.005, Date)
  TempRmCntrlSig = (TempRmCntrlSigz * 100)
  DamperPositionz = .25

   EndByteCode
   Status : Active
  EndObject

If that is not possible this variation is also okay:

   Type : InfinityProgram
   LastChange : 2/18/2025 5:15:38 PM
   DeviceId : NetWork_MankatoO\OfcDmp\Vav5_26
   Alias : RmTempSignalPRG
   CreateTime : 2/18/2025 5:13:20 PM
   CreatedBy : Root\Acc
   TimeLocked : 2/18/2025 5:15:38 PM
   InstanceId : 7227/33
   ByteCode :
Numeric TempRmCntrlSigz 
Numeric DamperPositionz

'ROOM TEMPERATURE CONTROL SIGNAL CALCULATIONS      ' Dylan Salisbury  Paape Energy Services     5/19/23

Numeric sync, lasthour
Numeric actn '     control loop "action" 1 or 0 (direct or reverse)

Line StartUp
  Goto RmHappy

Line RmHappy
  If ((IntrLkSystemRun = On) & (TempRmAvg > (StptRoom + 1)) & (TS > 2)) then Goto RmWarm
  TempRmCntrlSig = 50
  DamperPositionz = .5

Line RmWarm
  If ((IntrLkSystemRun = Off) or (TempRmAvg < StptRoom)) then Goto RmHappy
  TempRmCntrlSigz = PID11Fct(TempRmAvg, StptRoom, PIDTR[1], PIDTR[2], PIDTR[3], 0.5, actn, PIDTR[4], PIDTR[5], 0.5, 1, TempRmCntrlSigz, 0.005, Date)
  TempRmCntrlSig = (TempRmCntrlSigz * 100)
  DamperPositionz = .25

   EndByteCode
   Status : Active
  EndObject

This is the find and replace that I had tried:

Find: (Object(?s:(?!Object).)*?ByteCode :)((?s:(?!Object).)*?.*(?!Numeric \3).*?(?: |\(|^)([a-zA-Z0-9_]*?z)(?s:.*?)EndObject)

Replace:\1\nNumeric \3\2


Solution

  • This is one way of doing this. It finds unique (non-duplicate) Numeric Z's.
    And puts them in a line at the start of the code.

    Edited: This was refactored and added extra \b protection on dup check assertions.
    Also added segment to not go beyond the EndByteCode.
    And fixed a duplicate group printing in the NP++ (boost extended) replacement string.

    (?s)(Object(?:(?!Object).)*?ByteCode[ \t]*:[ \t]*\R+)((?:(?:(?!EndByteCode).)*?(?:(?(3)(?!))(\b\w*?z\b)|(?(4)(?!))(?!\3\b)(\b\w*?z\b)|(?(5)(?!))(?!\b(?:\3|\4)\b)(\b\w*?z\b)|(?(6)(?!))(?!\b(?:\3|\4|\5)\b)(\b\w*?z\b)|(?(7)(?!))(?!\b(?:\3|\4|\5|\6)\b)(\b\w*?z\b)|(?(8)(?!))(?!\b(?:\3|\4|\5|\6|\7)\b)(\b\w*?z\b)|(?(9)(?!))(?!\b(?:\3|\4|\5|\6|\7|\8)\b)(\b\w*?z\b))){1,7})
    

    https://regex101.com/r/4TtrDt/1

    Generic replacement would be $1Numeric $3, $4, $5, $6, $7, $8, $9\r\n\r\n$2
    NP++ replacement using conditionals would be :
    $1Numeric $3(?4, $4:)(?5, $5:)(?6, $6:)(?7, $7:)(?8, $8:)(?9, $9:)\r\n\r\n$2

    This regex will match/save up to 7 unique Numeric Z's. That can be increased to as many unique as expected.

    (?s)
    (                             # (1 start)
       Object
       (?:
          (?! Object )
          . 
       )*?
       ByteCode [ \t]* : [ \t]* \R+ 
    )                             # (1 end)
    (                             # (2 start)
       (?:
          (?:
             (?! EndByteCode )
             . 
          )*?
          (?:
             (?(3) (?!) )
             ( \b \w*? z \b )              # (3)
           | 
             (?(4) (?!) )
             (?! \3 \b )
             ( \b \w*? z \b )              # (4)
           | 
             (?(5) (?!) )
             (?! \b (?: \3 | \4 ) \b )
             ( \b \w*? z \b )              # (5)
           | 
             (?(6) (?!) )
             (?!  \b (?: \3 | \4 | \5 ) \b )
             ( \b \w*? z \b )              # (6)
           | 
             (?(7) (?!) )
             (?!  \b (?: \3 | \4 | \5 | \6 ) \b )
             ( \b \w*? z \b )              # (7)
           | 
             (?(8) (?!) )
             (?!  \b (?: \3 | \4 | \5 | \6 | \7 ) \b )
             ( \b \w*? z \b )              # (8)
           | 
             (?(9) (?!) )
             (?!  \b (?: \3 | \4 | \5 | \6 | \7 | \8 ) \b )
             ( \b \w*? z \b )              # (9)
          )
       ){1,7}
    )                             # (2 end)