Сделать отрицательный просмотр вперед без учета регистра

У меня есть следующее выражение:

$exp = "/^(?!.*?that).*$/";

который предназначен для соответствия любой строке, которая не содержит «это».

У меня есть следующие три предложения:

$str = array(   
   "I like this sentence.", #line1
   "I like that sentence.", #line2
   "I link THAT sentence."  #line3
);

Соответствие чувствительно к регистру, поэтому сопоставляются только строки 1 и 3. Все идет нормально.

Однако я хотел бы сделать его нечувствительным к регистру, чтобы он соответствовал только строке 1. Я пытался использовать встроенный модификатор, то есть «(?-i ...)»:

$exp = "/^(?!.*?(?i:that)).*$/";

и как флаг, т.е. "/ ... /i":

$exp = "/^(?!.*?that).*$/i";

но безрезультатно.

Я запускаю поиск со следующим циклом:

foreach($str as $s) {
    preg_match_all($exp, $s, $matches); 
    var_dump($matches);
}

с выходом:

array (size=1)
  0 => 
    array (size=1)
      0 => string 'I like this sentence.' (length=21)
array (size=1)
  0 => 
    array (size=0)
      empty
array (size=1)
  0 => 
    array (size=1)
      0 => string 'I link THAT sentence.' (length=21)

онлайн-демонстрация доступна здесь: https://regex101.com/r/bs9rzF/1

Я был бы признателен за любые советы о том, как сделать регулярное выражение нечувствительным к регистру.

EDIT: я неправильно использовал "?-i" вместо "?-i", как правильно указывают некоторые участники. Исправлено сейчас.


person msoutopico    schedule 10.06.2017    source источник
comment
$exp = "/^(?!.*?that).*$/i"; правильно и должно работать. Однако (?-i:... отключает модификатор i. Чтобы включить его: (?i:...   -  person Casimir et Hippolyte    schedule 10.06.2017
comment
Ваша вторая попытка с $exp = "/^(?!.*?that).*$/i"; должна сработать.   -  person revo    schedule 10.06.2017
comment
Действительно, кажется, что проблема, которая сделала поиск чувствительным к регистру независимо от модификатора i, была где-то в другом: флаг u также нужен для языков с акцентами и другими алфавитами, т.е. "/^(?!.*?that).*$/ui" Спасибо за ваши быстрые ответы!   -  person msoutopico    schedule 11.06.2017


Ответы (2)


Ваше первое регулярное выражение ^(?!.*?that).*$ не имеет ничего общего с чувствительностью к регистру, поскольку вы не используете модификатор для нечувствительности к регистру.

Регулярное выражение соответствует первому и третьему предложениям, потому что ваше регулярное выражение говорит о том, что в предложении не должно быть слова that (с учетом регистра), что верно для первого и третье предложение (в третьем предложении есть ЭТО, что не совпадает с это)

Чтобы соответствовать только первому предложению, вы можете использовать встроенный модификатор (?i), например

(?i)^(?!.*?that).*$

См. here

Кстати, ваше регулярное выражение /^(?!.*?that).*$/i также верно.

person rock321987    schedule 10.06.2017

Вы были рядом:

^(?!.*?(?i)that).*$

См. демонстрацию на сайте regex101.com. В своем выражении ((?-i)) вы отключали модификатор off.

person Jan    schedule 10.06.2017