String input =I needed to split this into two separate messages, both containing the header (MSH...PV1|||) and each containing one of the ORC/OBR/ZDS segment groups.
"MSH|^~\\&|||||||ORM^O01|\r" +
"PID|||\r" +
"PV1|||\r" +
"ORC|NW||||Registered\r" +
"OBR||ASDF00001||||||||||||||||||ASDF01000\r" +
"ZDS|1.2.752.24.2.5234.234.123.14.23\r" +
"ORC|NW||||Registered\r" +
"OBR||ASDF01000||||||||||||||||||ASDF01000\r" +
"ZDS|1.2.752.24.2.5234.234.123.14.23\r";
I'm currently reading the (so far) excellent book "Mastering Regular Expressions" by Friedl so why not use regular expressions for this, I thought!
First try (these are from memory, not sure I get them right):
Pattern getHeader = Pattern.compile("(MSH\\|[^ORC]*)",Pattern.MULTILINE | Pattern.DOTALL)
Well, this won't work since [^] is a character class and matches any of the O, R or C characters. Next try:
(MSH\\|.*ORC)This pattern won't work because by default regexp matches greedily so MSH...ORC|...ORC|... would be matched.
After flipping around in the book for a while I discovered lazy quantifiers. But the Friedl had an example on the same page where this problem could be solved by negative lookahead.
The final result:
This pattern matches:
(^MSH(?:(?!^ORC).)*)(.*)
- Beginning of line
- MSH
- Any character as long as the next characters aren't beginning of line and ORC
Similarly I can get the ORC/OBR/ZDS segments with the pattern:
^(ORC(?:(?!^ORC).)*)which matches:
- Beginning of line
- any character as long as the next ones aren't beginning of line and ORC
Final source:
public ListfilterMessageString(String input) {
Listresult = new ArrayList ();
// first get the header
Pattern getHeader = Pattern.compile("(^MSH(?:(?!^ORC).)*)(.*)", Pattern.MULTILINE | Pattern.DOTALL);
Matcher m = getHeader.matcher(input);
m.find();
String header = m.group(1);
if(logger.isDebugEnabled())
logger.debug("header: " + header);
// get the orc-obr-zds groups
String ORCGroups = m.group(2);
Pattern getNextOBR = Pattern.compile("^(ORC(?:(?!^ORC).)*)", Pattern.MULTILINE | Pattern.DOTALL);
m = getNextOBR.matcher(ORCGroups);
while(m.find()) {
if(logger.isDebugEnabled())
logger.debug("Found segment: " + m.group(1));
result.add(header + m.group(1));
}
return result;
}