2013-09-11 53 views
1

Так что в основном, я просто пытаюсь найти строку в строке.Как найти первое вхождение внутри строки в PHP?

Хотя, это немного сложнее, чем это.

У меня есть три маленькие струны, one, two, three

И у меня есть одна большая строка, которая сохраняется в переменной и довольно длинный .. длинный Несколько пунктов на самом деле.

Мне нужно создать функцию, которая позволяет мне увидеть, какая строка будет первой.

Например, строка так:

Hello, testing testing one test some more two 

Вернется one, так как это происходило до two.

Другой пример:

Test a paragraph three and testing some more one test test two 

Вернется three, так как это произошло до того как one и two.

Есть ли у кого-нибудь какие-либо предложения или примеры того, как это сделать? Очень новичок в PHP и не уверен, как это сделать. Благодаря!

+1

Использование 'stripos' на каждой "маленькой строки" и посмотреть, что позиция является минимальным? – Passerby

+0

Вы хотите, чтобы позиция или только какая строка была первой? –

ответ

1

попробовать что-то вроде этого:

$string = 'Hello, testing testing one test some more two'; 
$words = Array("one", "two", "three"); 
$low_pos = strlen($string); 
$first = ''; 
foreach($words as $word) 
{ 
    $pos = strpos($string, $word); 
    echo "Found ".$word." at ".$pos."<br />"; 
    if($pos !== false && $pos < $low_pos) 
    { 
     $low_pos = $pos; 
     $first = $word; 
    } 
} 

echo $string."<br />"; 
echo "FIRST: ".$first; 

Выходные:

Found one at 23 
Found two at 42 
Found three at 
Hello, testing testing one test some more two 
FIRST: one 
+0

Ваш ответ работал без проблем, спасибо! – Fizzix

1

См http://www.php.net/manual/en/function.strpos.php

Просто что-то вроде

$longString = "Hello, testing testing one test some more two"; 
$onePosition = strpos($longString, "one"); 
$twoPosition = strpos($longString, "two"); 
$threePosition = strpos($longString, "three"); 

$onePosition; // 23 
$twoPosition; // 42 
$threePosition; // -1 

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

+0

Но не будет ли '$ threePosition' быть самым низким, так как это' -1'? – Fizzix

+0

Вы проверили бы для> 0. – andrewb

+0

strpos() возвращает false, если игла не найдена (не -1). Вы должны сначала проверить, что каждая переменная не является ложной, а затем сравнивать те, которые не противоречат друг другу. –

1

Это должно работать:

<?php 

    $arrWords = array("one", "two", "three"); 
    $strInput = "Test a paragraph three and testing some more one test test two"; 

    function getFirstOccurrence($strInput, $arrWords) { 
     $arrInput = explode(" ", $strInput); 
     foreach($arrInput as $strInput) { 
      if(in_array($strInput, $arrWords)) { 
       return $strInput; 
      } 
     } 
     return null; 
    } 

    print "First word is: " . getFirstOccurrence($strInput, $arrWords); 

?> 
+0

Думайте, что ваш ответ, вероятно, самый надежный, особенно с реализацией поиска массива. Спасибо за вашу помощь! – Fizzix

1

Вот алгоритм выборки:

function getFirstWord(array $needles, $haystack) { 
    $best = null; //the best position 
    $first = null; //the first word 

    foreach($needles as $needle) { 
     $pos = strpos($haystack, $needle); 
     if($pos !== false) { 
      if($best === null || $pos < $best) { 
       $best = $pos; 
       $first = $needle; 
      } 
     } 
    } 

    //returns the first word, or null if none of $needles found 
    return $first; 
} 

$needles = array('one', 'two', 'three'); 
echo getFirstWord($needles, 'Hello, testing testing one test some more two'); // one 
echo getFirstWord($needles, 'Test a paragraph three and testing some more one test test two'); // three 

Оптимальное решение позволит свести к минимуму итераций по сравнению с $ стога. Вы можете начать с начала строки, и каждый раз, когда вы продвигаете символ, ищите любую из $ игл, начиная с текущей позиции. Как только вы найдете один, лото.

3

Использование preg_match() с простым чередованием:

if (preg_match('/one|two|three/', $string, $matches)) { 
    echo $matches[0]; 
} 

Результаты:

Hello, testing testing one test some more two 
-> one 

Test a paragraph three and testing some more one test test two 
-> three 

Если вам нужно место, а также, вы можете добавить флаг:

if (preg_match('/one|two|three/', $string, $matches, PREG_OFFSET_CAPTURE)) { 
    echo 'Found ' . $matches[0][0] . ' @ ' . $matches[0][1]; 
} 

В функции:

function findFirst($string, array $needles) 
{ 
    $pattern = '/' . join('|', array_map(function($str) { 
     return preg_quote($str, '/'); 
    }, $needles)) . '/'; 

    if (preg_match($pattern, $string, $matches)) { 
     return $matches[0]; 
    } else { 
     return false; 
    } 
} 

Применение:

echo findFirst($string, array('one', 'two', 'three')); 
+0

Отличный ответ, хотя я считаю, что функция легче читать и модифицировать. Определенно будет использовать этот следующий раунд, поскольку он намного упрощен. Благодаря! – Fizzix

+1

@fizzix Я обновил свой ответ, чтобы включить функцию, которая будет выглядеть. –

0

Если вы хотите получить Вы можете использовать закрытие с array_map, array_filter, array_search и min.

function whichFirst(array $list, $string){ 
    // get a list of the positions of each word 
    $positions = array_map(function($val) use ($string){ 
           return strpos($string, $val); 
          }, $list); 
    // remove all of the unfound words (where strpos returns false) 
    $positions = array_filter($positions, function ($x){ return $x !== false; }); 

    // get the value with the key matching the lowest position. 
    $key = array_search(min($positions), $positions); 

    return $list[$key]; 
} 

Пример:

$str = "Hello, testing testing one test some more two"; 
$list = ["one","two","three"]; 

echo whichFirst($list, $str); 
// outputs one 
Смежные вопросы