1

I have my input as follows,

Input

StatusMsg:
seqId: 14043
timestamp: 140707
dId: "Sa01"
msgType: SEQUENCE
eventType: UPDATE_CMD
devContext {
   context: IDLE
   operationalMode: 1
   logHistory {
      start: 1404387563607
      end: 1404387563616
   }
}
manifest {
   timestamp: 1404387733059
   dev {
      dId: "Sa01"
      mainComponent {
         serialNum: "10001"
         deviceClass: "Sap"
         componentType: "Sa01"
         subcomponentNum: 1
      }
   }
   info {
      name: "Sa01"
      channels: 1
      lib {
         name: "l.bin"
         timestamp: 1404387733059
         version: "6870711ee"
         validStartDate: 1404387733059
      }
      activeSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "12.001"
         validStartDate: 1404387733059
      }
      activeCSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "03.001"
         validStartDate: 1404387733059
      }
   }
}
powerStatus {
   powerEvent: ON
   powerSource: AC
   chargerStatus: CHARGING
   batteryStatus: GOOD
}
status {
   msgHeader {
      messageId: 13
      timestamp: 1404387733059
      seqNum: 13
      sourceId: 13
      numOfParams: 0
   }
   infuserState: READY
   keypadLockout: UNLOCKED
}
cmdResponse {
   cmdType: A_PGM
   aPgm {
      dId: "Sa01"
      refId: 79
      request {
         refId: 79
         libId: "6870711eedb"
         channelId: 1
         lId: 1
         pgmType: FULL
         aPgmType: NEW
         externalId: "EXT_ID_9"
         stats {
            WG: 76230
            HG: 150500
            BS: 1790
         }
         multi: false
      }
      response {
         dId: "Sa01"
         files: 1.bin
         major: 338013710701
         status: Received
      }
   }
}
[2014-07-07 14:10:41.034] I/O Received
StatusMsg:
seqId: 14043
timestamp: 140707
dId: "Sa01"
msgType: SEQUENCE
eventType: UPDATE_CMD
devContext {
   context: IDLE
   operationalMode: 1
   logHistory {
      start: 1404387563607
      end: 1404387563616
   }
}
manifest {
   timestamp: 1404387733059
   dev {
      dId: "Sa01"
      mainComponent {
         serialNum: "10001"
         deviceClass: "Sap"
         componentType: "Sa01"
         subcomponentNum: 1
      }
   }
   info {
      name: "Sa01"
      channels: 1
      lib {
         name: "l.bin"
         timestamp: 1404387733059
         version: "6870711ee"
         validStartDate: 1404387733059
      }
      activeSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "12.001"
         validStartDate: 1404387733059
      }
      activeCSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "03.001"
         validStartDate: 1404387733059
      }
   }
}
powerStatus {
   powerEvent: ON
   powerSource: AC
   chargerStatus: CHARGING
   batteryStatus: GOOD
}
status {
   msgHeader {
      messageId: 13
      timestamp: 1404387733059
      seqNum: 13
      sourceId: 13
      numOfParams: 0
   }
   infuserState: READY
   keypadLockout: UNLOCKED
}
cmdResponse {
   cmdType: A_PGM
   aPgm {
      dId: "Sa01"
      refId: 79
      request {
         refId: 79
         libId: "6870711eedb"
         channelId: 1
         lId: 1
         pgmType: FULL
         aPgmType: NEW
         externalId: "EXT_ID_9"
         stats {
            WG: 76230
            HG: 150500
            BS: 1790
         }
         multi: false
      }
      response {
         dId: "Sa01"
         files: 1.bin
         major: 35723057325
         status: Valid
      }
   }
}
[2014-07-07 14:15:71.028] I/O Received
StatusMsg:
seqId: 14043
timestamp: 140707
dId: "Sa01"
msgType: SEQUENCE
eventType: UPDATE_CMD
devContext {
   context: IDLE
   operationalMode: 1
   logHistory {
      start: 1404387563607
      end: 1404387563616
   }
}
manifest {
   timestamp: 1404387733059
   dev {
      dId: "Sa01"
      mainComponent {
         serialNum: "10001"
         deviceClass: "Sap"
         componentType: "Sa01"
         subcomponentNum: 1
      }
   }
   info {
      name: "Sa01"
      channels: 1
      lib {
         name: "l.bin"
         timestamp: 1404387733059
         version: "6870711ee"
         validStartDate: 1404387733059
      }
      activeSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "12.001"
         validStartDate: 1404387733059
      }
      activeCSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "03.001"
         validStartDate: 1404387733059
      }
   }
}
powerStatus {
   powerEvent: ON
   powerSource: AC
   chargerStatus: CHARGING
   batteryStatus: GOOD
}
status {
   msgHeader {
      messageId: 13
      timestamp: 1404387733059
      seqNum: 13
      sourceId: 13
      numOfParams: 0
   }
   infuserState: READY
   keypadLockout: UNLOCKED
}
cmdResponse {
   cmdType: A_PGM
   aPgm {
      dId: "Sa01"
      refId: 79
      request {
         refId: 79
         libId: "6870711eedb"
         channelId: 1
         lId: 1
         pgmType: FULL
         aPgmType: NEW
         externalId: "EXT_ID_9"
         stats {
            WG: 76230
            HG: 150500
            BS: 1790
         }
         multi: false
      }
      response {
         dId: "Sa01"
         files: 1.bin
         major: 27151510570
         status: Accepted
      }
   }
}
[2014-07-07 14:15:51.034] I/O Received
StatusMsg:
seqId: 14043
timestamp: 140707
dId: "Sa01"
msgType: SEQUENCE
eventType: UPDATE_CMD
devContext {
   context: IDLE
   operationalMode: 1
   logHistory {
      start: 1404387563607
      end: 1404387563616
   }
}
manifest {
   timestamp: 1404387733059
   dev {
      dId: "Sa01"
      mainComponent {
         serialNum: "10001"
         deviceClass: "Sap"
         componentType: "Sa01"
         subcomponentNum: 1
      }
   }
   info {
      name: "Sa01"
      channels: 1
      lib {
         name: "l.bin"
         timestamp: 1404387733059
         version: "6870711ee"
         validStartDate: 1404387733059
      }
      activeSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "12.001"
         validStartDate: 1404387733059
      }
      activeCSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "03.001"
         validStartDate: 1404387733059
      }
   }
}
powerStatus {
   powerEvent: ON
   powerSource: AC
   chargerStatus: CHARGING
   batteryStatus: GOOD
}
status {
   msgHeader {
      messageId: 13
      timestamp: 1404387733059
      seqNum: 13
      sourceId: 13
      numOfParams: 0
   }
   infuserState: READY
   keypadLockout: UNLOCKED
}
cmdResponse {
   cmdType: A_PGM
   aPgm {
      dId: "Sa01"
      refId: 79
      request {
         refId: 79
         libId: "6870711eedb"
         channelId: 1
         lId: 1
         pgmType: FULL
         aPgmType: NEW
         externalId: "EXT_ID_9"
         stats {
            WG: 76230
            HG: 150500
            BS: 1790
         }
         multi: false
      }
      response {
         dId: "Sa01"
         files: 1.bin
         major: 35723057325
         status: Valid
      }
   }
}

I want to ensure the following is mandatory to be present in the input with same order,

StatusMsg:
dId: "Sa01"
eventType: UPDATE_CMD
cmdResponse
cmdType: A_PGM
response
dId: "Sa01"
status: Accepted

Expected Output

StatusMsg:
seqId: 14043
timestamp: 140707
dId: "Sa01"
msgType: SEQUENCE
eventType: UPDATE_CMD
devContext {
   context: IDLE
   operationalMode: 1
   logHistory {
      start: 1404387563607
      end: 1404387563616
   }
}
manifest {
   timestamp: 1404387733059
   dev {
      dId: "Sa01"
      mainComponent {
         serialNum: "10001"
         deviceClass: "Sap"
         componentType: "Sa01"
         subcomponentNum: 1
      }
   }
   info {
      name: "Sa01"
      channels: 1
      lib {
         name: "l.bin"
         timestamp: 1404387733059
         version: "6870711ee"
         validStartDate: 1404387733059
      }
      activeSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "12.001"
         validStartDate: 1404387733059
      }
      activeCSW {
         name: "Sa01"
         timestamp: 1404387733059
         version: "03.001"
         validStartDate: 1404387733059
      }
   }
}
powerStatus {
   powerEvent: ON
   powerSource: AC
   chargerStatus: CHARGING
   batteryStatus: GOOD
}
status {
   msgHeader {
      messageId: 13
      timestamp: 1404387733059
      seqNum: 13
      sourceId: 13
      numOfParams: 0
   }
   infuserState: READY
   keypadLockout: UNLOCKED
}
cmdResponse {
   cmdType: A_PGM
   aPgm {
      dId: "Sa01"
      refId: 79
      request {
         refId: 79
         libId: "6870711eedb"
         channelId: 1
         lId: 1
         pgmType: FULL
         aPgmType: NEW
         externalId: "EXT_ID_9"
         stats {
            WG: 76230
            HG: 150500
            BS: 1790
         }
         multi: false
      }
      response {
         dId: "Sa01"
         files: 1.bin
         major: 27151510570
         status: Accepted
      }
   }
}

I tried with the regular expression,

(StatusMsg:.*?dId:\s*"Sa01".*?eventType: UPDATE_CMD.*?response\s*{[\s\n\w\.:]*dId:\s*"Sa01"[\s\n\w\.:]*status:\s*Accepted)

The above expression selects from the first StatusMsg till Accepted. Can anyone help in framing the right regular expression?

MIZ
  • 385
  • 1
  • 14

1 Answers1

1

You only need a small change to your regex to do this. Note that with your regex you also need the m flag at the end.

The updated regex:

/(StatusMsg:(?!.*StatusMsg:).*?dId:\s*"Sa01".*?eventType: UPDATE_CMD.*?response\s*{[\s\n\w\.:]*dId:\s*"Sa01"[\s\n\w\.:]*status:\s*Accepted)/m

Note: For testing with rubular, strip the / at the beginning and /m at the end, and put the m in the small text box to the right of the one where you're entering your regex. This sets the m flag to apply, which acts to cause . in your regex to match newlines (not the default behavior).

The only thing that's changed there is that

StatusMsg:.*?

has become

StatusMsg:(?!.*StatusMsg:).*?

This works with negative lookaheads. This is in effect telling your regex to only match where your regex matches but only when the match does not contain two lots of the string StatusMsg.

If StatusMsg always comes at the beginning of the line with no preceding whitespace, you could make this slightly more specific by doing:

^StatusMsg:(?!.*^StatusMsg:).*?

bdx
  • 3,316
  • 4
  • 32
  • 65
  • Thanks for the solution. Your solution works only if the matched section is in the last part of the input. I have modified the input so that my expected match is not the last set of messages. Can you help me in selecting the expected match for the current input? – MIZ Jul 08 '14 at 04:20
  • Hmm. Haven't come up with a pure regex solution yet; but you could make it easier on yourself by doing `input_str.split(/^StatusMsg/)` and then iterating through returned objects in the array searching for the patterns you want. – bdx Jul 08 '14 at 12:13
  • Anyone got answer for this problem – MIZ Jun 16 '15 at 12:56