0

I've been racking my brain for hours on this and I'm at my wit's end. I'm beginning to think that this isn't possible for a regular expression.

The closest thing I've seen is this post: Regular expression to match a line that doesn't contain a word?, but the solution doesn't work when I replace "hede" with the number.

I want to select EACH line that DOES NOT contain: 377681 so that I can delete it.

^((?!377681).)*$ 

...doesn't work, along with thousands of other examples/tweaks that I've found or done.

Is this possible?

Community
  • 1
  • 1
rahlzel
  • 41
  • 1
  • 6
  • You can't match what you don't want to match. – Dejan Marjanović Jul 29 '11 at 21:38
  • @webarto: Actually, there is an algorithm which takes an FA recognizing a language L over alphabet E and produces an FA recognizing L^C, the complement of L on E... so you are provably incorrect. – Patrick87 Jul 29 '11 at 21:51
  • @Patrick87, I'm sure there is, but negating the match would solve him his many hour brain wracking :) – Dejan Marjanović Jul 29 '11 at 21:54
  • Why don't you just invert the predicate? If you're using `grep`, use the `-v` command line option. If you're using a regex library in some programming language, change `if (matches)` to `if (!matches)`. – Adam Rosenfield Jul 29 '11 at 22:08
  • OP here. I might be able to help you help me. In EACH line is the string "Account:" (without quotes). Is there a way to select a line with "Account: XXX" within it, as long as it does NOT contain the number "377681"? – rahlzel Jul 29 '11 at 22:18
  • wrack (v) to destroy; rack (v) to torture – Andrew Kozak Jan 04 '12 at 16:21

5 Answers5

2

Would grep -v 377681 input_file solve your problem?

Fredrik Pihl
  • 44,604
  • 7
  • 83
  • 130
2

Try this one

^(?!.*377681).+$

See it here on Regexr

Important here is to use the m (multiline) modifier, so that ^ match the start of the line and $ the end of the row, other wise it will not work.

(Note: I recognized that my regex has the same meaning than yours.)

stema
  • 90,351
  • 20
  • 107
  • 135
  • If `^((?!377681).)*$` does not work in the OP's case, then `^(?!.*377681).+$` won't either, AFAIK. The problem lies in the fact that `^` and `$` do no match line-starts and endings. I.e., the `m` flag needs to be enabled. – Bart Kiers Jul 29 '11 at 21:48
  • @Bart, yep you are right (+1) (its a bit late, I needed some time to understand that `^((?!377681).)*$` is quite the same than my solution) – stema Jul 29 '11 at 21:57
  • Yeah, they do pretty much the same thing. A bit odd that you received a down-vote for an answer (your link does use the `m` flag!) that does work. I expect out math genius, Patrick87, to be a vindictive down-voter (my answer got down-voted as well) :) – Bart Kiers Jul 29 '11 at 22:03
  • @Bart I am already wondering why nearly every answer here is downvoted, since we know nothing about the context or the language and most of the answers are not bad/wrong. – stema Jul 29 '11 at 22:09
0

There's probably a better way of doing this, like for example iterating each line and asking for a built String method, like indexOf or contains depending on the language you're using.

Could you give us the full example?

Pablo Fernandez
  • 103,170
  • 56
  • 192
  • 232
0

You'll need to enable the m (multi-line) flag for the ^ and $ to match the start- and end-of-lines respectively. If you don't, ^ will match the start-of-input and $ will only match the end-of-input.

The following demo:

#!/usr/bin/env php
<?php
$text = 'foo 377681 bar
this can be 3768 removed
377681 more text
remove me';

echo preg_replace('/^((?!377681).)*$/m', '---------', $text);
?>

will print:

foo 377681 bar
---------
377681 more text
---------
Bart Kiers
  • 166,582
  • 36
  • 299
  • 288
0
<?php
$lines = array(
'434343343776815456565464',
'434343343774815456565464',
'434343343776815456565464'
);

foreach($lines as $key => $value){
    if(!preg_match('#(377681)#is', $value)){
        unset($lines[$key]);
    }   
}

print_r($lines);

?>
Dejan Marjanović
  • 19,244
  • 7
  • 52
  • 66