Php кілька роздільників у вибуху


146

У мене є проблема, у мене є рядковий рядок, і я хочу вибухнути різним роздільником. Наприклад

$example = 'Appel @ Ratte';
$example2 = 'apple vs ratte'

і мені потрібен масив, який вибухає в @ або vs.

Я вже писав рішення, але якщо у кожного краще рішення, будь ласка, опублікуйте тут.

private function multiExplode($delimiters,$string) {
    $ary = explode($delimiters[0],$string);
    array_shift($delimiters);
    if($delimiters != NULL) {
        if(count($ary) <2)                      
            $ary = $this->multiExplode($delimiters, $string);
    }
    return  $ary;
}

Я ніколи не бачив запитання з людьми, які давали відповіді на кшталт "Як щодо цього", "Як щодо цього"
HosseyNJF

Відповіді:


290

як щодо використання

$ output = preg_split ("/ (@ | vs) /", $ input);

Дивовижний. мені цікаво, як це explode()
стикається

6
Не має значення, якщо ви хочете зробити велику систему з жорстким розбором рядків, найефективнішим способом є власний парсер. Інакше це не має особливого впливу на швидкість роботи системи, але ви бажаєте скористатися найпростішим для вас способом (щоб бути ефективним)
SergeS

9
Зауважте, що деякі символи потрібно уникати для роботи (наприклад /, ?). Наприклад: preg_split("/(\/|\?|=)/", $foo);.
kenorb

preg_split повертає індексований масив. Можна повернути асоціативне? Наприклад $str='/x/1/2/3/4/5/y/100/200/z/777'; preg_split("/(x|y|z|)/", $str); і подивитисяarray('x'=>'1/2/3/4/5', 'y'=>'100/200', 'z'=>'777')
LINKeRxUA

2
Я виявив, що між проміжком / (і ) /зупинкою preg_split не працює. Мені довелося видалити пробіли, і тоді це спрацювало як очікувалося (використовуючи PHP 7)
Boardy

69

Ви можете взяти перший рядок, замінити всі @з vsдопомогою str_replace, а потім вибухати vsабо навпаки.


1
Просте рішення, зрештою, використовуючи його для коду Json для заміни "}}" на "|". Брудне, але ефективне :)!
Baldráni

5
який геній: D
Дедпул

це не спрацює належним чином, коли один роздільник є (@|@!)

2
@vaxquis Так, так і буде. str_replace ('@!', '@', $ str); Переконайтеся, що ви починаєте з найбільш унікального роздільника.
Джон Баллінгер

@JohnBallinger Ні, це не буде - ви запропонували інше рішення, в якому чітко видно, що оригінальне рішення не працюватиме належним чином, і що ваша ідея є хибною. Уявіть, ви не знаєте, який з них є сукупністю іншого. Вам доведеться створити інший рядок коду, щоб перевірити це на інше. Хоча я взагалі ненавиджу регулярні вирази, це той випадок, коли це найкраще рішення з точки зору ремонтопридатності та простоти.

47
function multiexplode ($delimiters,$string) {

    $ready = str_replace($delimiters, $delimiters[0], $string);
    $launch = explode($delimiters[0], $ready);
    return  $launch;
}

$text = "here is a sample: this text, and this will be exploded. this also | this one too :)";


$exploded = multiexplode(array(",",".","|",":"),$text);

print_r($exploded);

//And output will be like this:
// Array
// (
//    [0] => here is a sample
//    [1] =>  this text
//    [2] =>  and this will be exploded
//    [3] =>  this also 
//    [4] =>  this one too 
//    [5] => )
// )

Джерело: php @ metehanarslan на php.net


14

Як щодо використання strtr()підстановки всіх інших роздільників на перший?

private function multiExplode($delimiters,$string) {
    return explode(
        $delimiters[0],
        strtr(
            $string,
            array_combine(
                array_slice(    $delimiters, 1  ),
                array_fill(
                    0,
                    count($delimiters)-1,
                    array_shift($delimiters)
                )
            )
        )
    );
}

Напевно, це нечитабельно, але я перевірив це як працюючий тут.

Однолінійки ftw!


11

Ви б не strtok()працювали?


1
бачачи, що його роздільник є "проти", це може не спрацювати, як говорить php docu: strtok () розбиває рядок (str) на більш дрібні рядки (лексеми), причому кожен маркер відмечений будь-яким символом від маркера. і 'vs' містить два символи
mikewasmike

1
це буде кращою відповіддю, якби ви включили пояснення чи приклад. як це, це більше коментар ...
billynoah

8

Просто ви можете використовувати наступний код:

$arr=explode('sep1',str_replace(array('sep2','sep3','sep4'),'sep1',$mystring));

4

Ви можете спробувати це рішення .... Це чудово працює

function explodeX( $delimiters, $string )
{
    return explode( chr( 1 ), str_replace( $delimiters, chr( 1 ), $string ) );
}
$list = 'Thing 1&Thing 2,Thing 3|Thing 4';

$exploded = explodeX( array('&', ',', '|' ), $list );

echo '<pre>';
print_r($exploded);
echo '</pre>';

Джерело: http://www.phpdevtips.com/2011/07/exploding-a-string-using-multiple-delimiters-using-php/


простий і акуратний
Манойкіран.А

2

Я роблю це так ...

public static function multiExplode($delims, $string, $special = '|||') {

    if (is_array($delims) == false) {
        $delims = array($delims);
    }

    if (empty($delims) == false) {
        foreach ($delims as $d) {
            $string = str_replace($d, $special, $string);
        }
    }

    return explode($special, $string);
}

це те, що я шукав
Manojkiran.A

2

Як щодо цього?

/**
 * Like explode with multiple delimiters. 
 * Default delimiters are: \ | / and ,
 *
 * @param string $string String that thould be converted to an array.
 * @param mixed $delimiters Every single char will be interpreted as an delimiter. If a delimiter with multiple chars is needed, use an Array.
 * @return array. If $string is empty OR not a string, return false
 */
public static function multiExplode($string, $delimiters = '\\|/,') 
{
  $delimiterArray = is_array($delimiters)?$delimiters:str_split($delimiters);
  $newRegex = implode('|', array_map (function($delimiter) {return preg_quote($delimiter, '/');}, $delimiterArray));
  return is_string($string) && !empty($string) ? array_map('trim', preg_split('/('.$newRegex.')/', $string, -1, PREG_SPLIT_NO_EMPTY)) : false;
}

У вашому випадку ви повинні використовувати масив для параметра $ delimiters. Тоді можна використовувати кілька знаків як один роздільник.

Якщо вас не цікавить пробіли у ваших результатах, ви можете видалити array_map('trim', [...] )частину у рядку, що повертається. (Але в цьому випадку не будьте химерником. Зберігайте preg_splitце.)

Потрібна версія PHP: 5.3.0 або вище.

Ви можете протестувати його тут


1

У вас виникнуть деякі проблеми (що, наприклад, якщо у вас є такий рядок: "vs @ apples", наприклад), використовуючи цей метод розділення, але якщо ми почнемо з того, що ви думали про це, і виправили всі ці можливі зіткнення, ви могли б просто замінити всі входження $delimiter[1]в $delimiter[n]с $delimiter[0], а потім розділити на цій першій?


1

Якщо ваш роздільник лише символи, ви можете використовувати strtok, що, здається, тут більше підходить. Зауважте, що ви повинні використовувати його з whileциклом для досягнення ефектів.


0

Це спрацює:

$stringToSplit = 'This is my String!' ."\n\r". 'Second Line';
$split = explode (
  ' ', implode (
    ' ', explode (
      "\n\r", $stringToSplit
    )
  )
);

Як бачите, він спочатку склеює \ n \ r вибухані частини разом із пробілом, а потім знову розрізає його, цього разу беручи пробіли.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.