A solution using regular expression with Negative Lookahead (?!regex)
Before the Match:
string = "<hello>something WRONG</hello><hello>something else</hello><hello>WRONG</hello>";
StringCases[string,
"<hello>" ~~ st : RegularExpression["(?:(?!WRONG).)*?"] ~~ "</hello>" :> st]
{"something else"}
An alternative solution using pure regexes (should be more efficient):
StringCases[string, RegularExpression["(?ms)<hello>((?:(?!WRONG).)*?)</hello>"] :> "$1"]
{"something else"}
A detailed description of this method can be found here.
UPDATE
Performance comparison of the three methods including the improved solution by march (timings for version 10.4.1 on Win7 x64):
string = "<hello>something WRONG</hello><hello>something</hello><hello>something \
else</hello><hello>WRONG</hello>";
stringBig = StringJoin@ConstantArray[string, 3*^2];
First@AbsoluteTiming[
r1 = StringCases[stringBig,
"<hello>" ~~ Shortest[st__] ~~ "</hello>" /; StringFreeQ[st, "WRONG"] :> st]]
First@AbsoluteTiming[
r2 = StringCases[stringBig,
"<hello>" ~~ st : RegularExpression["(?:(?!WRONG).)*?"] ~~ "</hello>" :> st]]
First@AbsoluteTiming[
r3 = StringCases[stringBig,
RegularExpression["(?ms)<hello>((?:(?!WRONG).)*?)</hello>"] :> "$1"]]
r1 === r2 === r3
14.5705
0.00302571
0.00242202
True
As one can see, the StringExpression
(~~
) solution with Condition
(/;
) is more than 3 orders of magnitude slower than StringExpression
without it. What is unexpected is that pure RegularExpression
solution is slower than StringExpression
without Condition
. This topic was discussed before but an explanation was not found.
And here is the output obtained with the same code using version 8.0.4 on the same machine:
78.8455097
0.0030002
0.0040002
True
As one can see, there is significant speedup for string pattern with Condition
in version 10.4.1 as compared to 8.0.4.