Well, you're on the right track with preg_match - this would be a serious pain if you used ereg. You're going a bit off-course using character classes, since these only match single characters, not whole strings.
What preg_match() offers are assertions. In your case you want to match "X.*?X", while demanding that the bit between the Xs is neither "foo" nor "bar". In other words, the bit that follows the first X must not be "fooX" or "barX" (where the Xs are there so that "Xfoolish barristerX" still matches)
The syntax for making such a demand (a "forward negative assertion" in techspeak) is
code[/code]
The full regexp would be (note that I haven't tested this at all)
/X(?!fooX)(?!barX).*?X/
"'X', (which must not be followed by 'fooX', and must not be followed by 'barX'), followed by as few characters as possible before the next occurrence of 'X'".