2010-10-27 12 views
12

Załóżmy, że chcę zwrócić wszystkie znaki po znaku igły 'x' od:PHP substr po pewnym znaku, substr + strpos eleganckie rozwiązanie?

$source_str = "Tuex helo babe".

Normalnie bym to zrobić:

if(($x_pos = strpos($source_str, 'x')) !== FALSE) 
    $source_str = substr($source_str, $x_pos + 1); 

Znasz lepszy/Smarter (bardziej elegancki sposób), aby to zrobić?

Bez użycia wyrażenia regularnego, które nie sprawiłoby, że byłoby bardziej eleganckie i prawdopodobnie również wolniejsze.

Niestety nie możemy zrobić:

$source_str = substr(source_str, strpos(source_str, 'x') + 1); 

Bo kiedy 'x' nie znaleziono strpos powraca FALSE (a nie jak w -1 JS). FALSE wyliczyłoby zero, a pierwszy znak byłby zawsze odcięty.

Dzięki,

+2

Użyj swojego pierwszego podejścia. – Gumbo

+0

Nie możesz usunąć "! == FALSE" i w ten sposób będzie trochę bardziej kompaktowy? – Adam

+0

@Gumbo, obawiam się, że masz rację. Plz zapisz to jako odpowiedź, a ja wybieram twoje, chyba że wyjdzie coś lepszego. –

Odpowiedz

10

Twoje pierwsze podejście jest w porządku: Sprawdź, czy x jest zawarta z strpos a jeśli tak się nic po nim z substr.

Ale można też użyć strstr:

strstr($str, 'x') 

Ale jak to zwraca podciąg rozpoczynający zx użyć substr dostać część po x:

if (($tmp = strstr($str, 'x')) !== false) { 
    $str = substr($tmp, 1); 
} 

Ale to jest daleko bardziej skomplikowane. Zamiast tego użyj podejścia strpos.

+0

Ale strstr zwraca FALSE, jeśli igła nie zostanie znaleziona, a nie cały ciąg. –

+0

z PHP 5.3+ strstr() akceptuje opcjonalny trzeci parametr "before_needle", który umożliwia dołączenie lub wykluczenie igły. Więc nie trzeba już używać substr. –

0
if(strpos($source_str, 'x') !== FALSE) 
    $source_str = strstr($source_str, 'x'); 

Mniej elegancki, ale bez x na początku:

if(strpos($source_str, 'x') !== FALSE) 
    $source_str = substr(strstr($source_str, 'x'),1); 
+0

to będzie zawierało 'x' w $ source_str, ale – Adam

+0

Cóż, dziękuję za odpowiedź, ale można argumentować, że jest to bardziej eleganckie i zdecydowanie wolniejsze. "Jeśli chcesz tylko określić, czy dana igła występuje w stogu siana, użyj szybciej i mniej funkcji intensywniejszej pamięci strpos() zamiast. " [źródło: http://it.php.net/strstr] –

+0

Jestem zdezorientowany. 'strpos' to sprawdzanie występowania podłańcuchów i jest używane w mojej odpowiedzi. 'strstr' zwraca część łańcucha, tylko jeśli występuje podłańcuch. Uważam, że jest bardziej elegancki, ponieważ nie potrzebuje zmiennej pomocniczej, nie ma mylącego przypisania w linii 'if()' i jest krótszy. Jedyną wadą jest to, co @adam wspomniał o –

3

regexes byłoby to dużo bardziej eleganckie:

// helo babe 
echo preg_replace('~.*?x~', '', $str); 

// Tuex helo babe 
echo preg_replace('~.*?y~', '', $str); 

Ale zawsze możesz spróbować tego:

// helo babe 
echo str_replace(substr($str, 0, strpos($str, 'x')) . 'x', '', $str); 

// Tuex helo babe 
echo str_replace(substr($str, 0, strpos($str, 'y')) . 'y', '', $str); 
-1

Ap pend a '-' na końcu $item, więc zawsze zwraca ciąg przed "-" nawet $item nie zawiera "-", ponieważ domyślnie strpos zwraca pozycję pierwszego wystąpienia z "-".

substr($item,0,strpos($item.'-','-')) 
0

Potrzebowałem właśnie tego, a dążenie do utrzymania go w jednej linii dla zabawy wymyślił to:

ltrim(strstr($source_str, $needle = "x") ?: $source_str, $needle);

ternary operator został dostosowany w 5.3, aby umożliwić tym pracować.

Od PHP 5.3 można pominąć środkową część operatora trójskładnikowego. Wyrażenie wyrażenie1?: Wyrażenie3 zwraca wyrażenie1, jeśli wyrażenie1 wylicza wartość PRAWDA, a wyrażenie3 w przeciwnym wypadku.

NB. ltrim przycina wiele pasujących znaków na początku ciągu znaków.

Powiązane problemy