Reputation: 147
I need a regex to find lines of a file containing a string that is not preceded by another.
Specifically, I need to search for lines that contain the "fixed" string but they do not come preceded by "#" in any previous position. Examples:
fixed xxx
# fixed yyy
aaa # fixed zzz
fixed www # bbb
Regexp should return only this lines:
fixed xxx
fixed www # bbb
Can this be done with a single regex? How?
I'm using PHP.
Thank you all.
PD: Sorry for my English.
Upvotes: 1
Views: 104
Reputation: 8446
This is the regex you need (without using any lookarounds):
/^[^#\n]*fixed[^\n]*$/m
Explanation:
^ - beginning of a line
[^#\n]* - any amount of chars that are not "#" and are not line breaks
fixed - the string itself
[^\n]* - any other characters that are not line breaks
$ - until the end of a line
/m - multiline modifier: http://php.net/manual/ro/reference.pcre.pattern.modifiers.php
In PHP:
$lines = "fixed xxx\n# fixed yyy\naaa # fixed zzz\nfixed www # bbb";
$matches = array();
preg_match_all('/^[^#]*fixed.*$/m', $lines, $matches);
var_dump($matches);
Result:
array(1) {
[0]=>
array(2) {
[0]=>
string(9) "fixed xxx"
[1]=>
string(15) "fixed www # bbb"
}
}
thx to @sln for the suggestions.
Upvotes: 3
Reputation: 4095
Or the negative lookbehind way:
(?<!#\s)fixed.*
Example:
PHP:
$string = "fixed xxx
# fixed yyy
aaa # fixed zzz
fixed www # bbb";
preg_match_all("/(?<!#\s)fixed.*/", $string, $matches);
print_r($matches);
Output:
Array
(
[0] => Array
(
[0] => fixed xxx
[1] => fixed www # bbb
)
)
Upvotes: 0
Reputation:
This approach checks from the end of line back to beginning.
Incase of fixed # fixed
# '/^(?!.*\#.*fixed).*fixed.*/m'
^
(?! .* \# .* fixed )
.*
fixed
.*
Upvotes: 0
Reputation: 7434
Use Regex Negative Lookbehind: Live Demo
$reg = '/(?<!\#\s)(fixed.+)/';
$input = '
fixed xxx
# fixed yyy
aaa # fixed zzz
fixed www # bbb';
preg_match_all($reg, $input, $output);
$output = $output[0];
print_r($output);
Output:
Array
(
[0] => fixed xxx
[1] => fixed www # bbb
)
Upvotes: 0
Reputation: 304
Since the comparisons are all by line, I would try something like this...
(in pseudo code)
Regex regex = new Regex("^[0-9]"); //a string that starts with a number
string thisLine = input.getLine();
while(hasInput)
{
string lastLine = thisLine;
string thisLine = input.getLine();
if(regex.hasMatch(lastLine))
{
System.out.println(thisLine)
}
}
Upvotes: 0