I would like to match the word 'mice' without any words right before it, but my regex isn't working. What am I doing wrong?
<?php
$string1 = "one mice";
$string2 = "one .mice";
$string3 = "mice";
if (preg_match("~(?<![a-z]+ )\bmice~", $string1)) { echo "1"; }
if (preg_match("~(?<![a-z]+ )\bmice~", $string2)) { echo "2"; }
if (preg_match("~(?<![a-z]+ )\bmice~", $string3)) { echo "3"; }
?>
Expected Result:
23
Actual Result:
null
I expect it echo 2 because instead of having a word before 'mice', it's a period instead. And I expect it to echo 3 because there's no word before the word 'mice'. What am I doing wrong?
You can use negative lookbehind
and make the dot
optional, i.e.:
if (preg_match('/(?<![a-z] )\.?\bmice\b/i', $subject)) {
# Successful match
}
Regex explanation:
(?<![a-z] )\.?\bmice\b
Options: Case insensitive
Assert that it is impossible to match the regex below with the match ending at this position (negative lookbehind) «(?<![a-z] )»
Match a single character in the range between “a” and “z” (case insensitive) «[a-z]»
Match the character “ ” literally « »
Match the character “.” literally «\.?»
Between zero and one times, as many times as possible, giving back as needed (greedy) «?»
Assert position at a word boundary (position preceded or followed—but not both—by a Unicode letter, digit, or underscore) «\b»
Match the character string “mice” literally (case insensitive) «mice»
Assert position at a word boundary (position preceded or followed—but not both—by a Unicode letter, digit, or underscore) «\b»
Note:
(?<![a-z]+ )