tags:

views:

94

answers:

3

I have the problem i want to get these numbers, BUT only when then dont come an "foo"

Example: "12:13 Foo" (no) "12:22 Bla" (yes)

i have the Regex: (\d+):(\d+) and dont know what to do that it dont select strings with the "Foo" after the digits

A: 

(\d+):(\d+) (\s*)(^[Ff]^[Oo]^[Oo])(\s*)

jetru
The `^` now matches the start of the input, it does not negate, as you probably think it does. It only negates when placed at the start of a character class: `[^a]` matches any character except an `a`.
Bart Kiers
+3  A: 

This depends somewhat on your regex flavour, but if it supports lookaround you can use:

(\d+):(\d+)(?:\s+(?!Foo)|$)

This doesn't, however, match 12:34Bar (no space between the 4 and B).

Another edit: If you can use atomic groping, then I think this will cover the cases where there's no space between the last digit and the word following it as well as the previous cases (rubular link):

(\d+):(?>\d+)(?!\s*F[oO][oO]) 

#Or just (\d+):(?>\d+)(?!\s*Foo) if case-insensitive
eldarerathis
@mullek, note that this only works if your `\d+:\d+` is at the start of the input string. If you're searching a string for these occurrences, remove the `^` and `$` from the suggested regex.
Bart Kiers
@eldarerathis, that won't match `12:22 Bla` since the regex only matches strings ending with `\s*$`
Bart Kiers
@mullek: Yes, @Bart Kiers makes an excellent point. If this pattern exists in the middle of a string then remove the anchors (`^` and `$`).
eldarerathis
Nope, `(\d+):(\d+)\s+[^Ff][^Oo][^Oo]` will not match `11:11 AB` to name just one string. I'd just roll back and only leave `(\d+):(\d+)\s*(?!Foo)` in place.
Bart Kiers
@Bart Kiers: Hm, that's true. I'll just roll with what we know works.
eldarerathis
(\d+):(\d+)\s*(?!Foo) dont work, but (\d+):(\d+)\s(?!Foo) do but dont mathes with 1:1)
mullek
@NullUserException: I just realized - I meant to use `\s+`, otherwise the `*` gives back its space and does match `12:34 Foo` (unless it's made posessive). I've amended that. That creates another complexity, though.
eldarerathis
@eldarerathis, no, changing `\s*` into `\s+` will only make it fail to match the string `12:34` (without a space after it). Like I said: include the `\s*`, or `\s+` inside the look-ahead and you're done.
Bart Kiers
@Bart Kiers: `(\s+(?!Foo)|$)` fixes the `12:34` with no space after it issue. I tried `(\d+):(\d+)(?!\s*Foo)` again in Python and it matched `12:34 Foo`. Edit: Actually, the issue is that it matches `12:3` with the `(\d+):(\d+)` and then the last digit matches the `(?!\s*Foo)`, disregarding the fact that ` Foo` comes one character later.
eldarerathis
I know it fixes it, I just find it too complicated. See my answer, which I think is much easier to read, and does practically the same.
Bart Kiers
+1  A: 

(updated answer)

(\d+):(\d+)(?:\s(?!\s*Foo)|$)

By adding a negative lookahead (?!Foo), it will only match strings which don't end with "Foo". It will also capture the two digit groups into backreferences 1 and 2.

Matches:

  • 12:34
  • 12:22 Bla
  • 1:1

Won't match:

  • 12:13 Foo
  • 12:13Foo
  • 12:13 Foo
Colin O'Dell
But it will not match `11:11 Foo` (two spaces between `11` and `Foo`) or `22:22` (without a space)
Bart Kiers
Yes, I suppose I should have added that disclaimer :p This regex assumes there is exactly one space in between (per the examples provided). If the number of spaces is unknown or varies, changing `\s` to `\s*` will allow that.
Colin O'Dell
+1 This one works.
NullUserException
Note that I voted your answer down before I answered myself (else I hadn't done so). I did so because @mullek specifically mentioned an earlier answer of @eldarerathis being incorrect because it did not match `1:1`: something your answer also does not match (and is therefor incorrect).
Bart Kiers