php
  • regex
  • 2013-08-26 3 views 1 likes 
    1

    Я пытаюсь извлечь все индексы определенного слова из строки, используя PHP preg_match. Возьмем, например, слово hello:PHP preg_match возвращает неверные индексы

    $r = "/\b(hello)\b/u"; 
    

    Скажем, я хочу, чтобы искать его в этой строке:

    $s = 'hello. how are you, hello there. helloorona!'; 
    

    Если я бегу preg_match с параметром PREG_OFFSET_CAPTURE и переходя в массив с именем $ спичек,

    preg_match($r, $s, $matches, PREG_OFFSET_CAPTURE); 
    

    Я ожидал что-то подобное должно быть возвращено (т.е. без учета последнего «hellooroona» фразу):

    ["hello", 0], ["hello", 20] 
    

    , но на самом деле, когда я вернусь эхо значение $matches либо через json_encode или перекручивание во всех матчах, возвращенное значение всегда:

    ["hello", 0], ["hello", 0] 
    

    Если я бегу это на подобную строку , скажем

    $s = 'how are you, hello there.'; 
    

    ответ

    ["hello", 13] 
    

    , который является правильным. Запустите ее на hello hello hello и я получаю три индекса, все 0.

    Резюме

    Так что похож индекс счетчиком просто всегда возвращает первый индекс. Это ожидаемое поведение? Как получить фактические индексы?

    +0

    последний привет не показывается, потому что вы используете '\ b' которое граница слова, например, что-нибудь до/после этого не слово персонаж, он захватит его. – Class

    ответ

    1

    Второй ["hello", 0] не второй привет в вашей строке, а совпадение подгруппы.

    Использование preg_match_all который даст вам ожидаемый результат:

    // note: sub group is not necessary 
    $r = "/\bhello\b/u"; 
    $s = 'hello. how are you, hello there. helloorona!'; 
    preg_match_all($r, $s, $matches, PREG_OFFSET_CAPTURE); 
    
    +0

    Да, вы правы, я пытался использовать 'preg_match_all', но также не получил того, чего ожидал, - удаление подгруппы - это то, что в конце концов решило. Благодаря! –

    2

    preg_match соответствует соответствует, а затем останавливается. В массиве результатов всегда содержится полное совпадающее выражение в его 0 индексе и все группы захвата в следующих индексах, начиная с 1. Например .:

    preg_match('/foo (\w+)/', 'foo bar', $r) 
    

    $r здесь содержит 0 => 'foo bar', 1 => 'bar'.

    Так что в вашем случае вы просто видите первый из первых hello из-за этого.

    Если вы хотите совместить все вхождения выражения, используйте preg_match_all.

    Смежные вопросы