PHP는 문자열을 폭발하지만 인용문으로 단어를 한 단어로 취급합니다.

StackOverflow https://stackoverflow.com/questions/2202435

문제

다음 문자열을 어떻게 폭발시킬 수 있습니까?

Lorem ipsum "dolor sit amet" consectetur "adipiscing elit" dolor

~ 안으로

array("Lorem", "ipsum", "dolor sit amet", "consectetur", "adipiscing elit", "dolor")

인용문의 텍스트가 단일 단어로 취급되도록합니다.

지금은 다음과 같습니다.

$mytext = "Lorem ipsum %22dolor sit amet%22 consectetur %22adipiscing elit%22 dolor"
$noquotes = str_replace("%22", "", $mytext");
$newarray = explode(" ", $noquotes);

그러나 내 코드는 각 단어를 배열로 나눕니다. 따옴표 마크 내부에서 한 단어로 취급 된 단어를 어떻게 만들려면?

도움이 되었습니까?

해결책

당신은 a를 사용할 수 있습니다 preg_match_all(...):

$text = 'Lorem ipsum "dolor sit amet" consectetur "adipiscing \\"elit" dolor';
preg_match_all('/"(?:\\\\.|[^\\\\"])*"|\S+/', $text, $matches);
print_r($matches);

생산할 :

Array
(
    [0] => Array
        (
            [0] => Lorem
            [1] => ipsum
            [2] => "dolor sit amet"
            [3] => consectetur
            [4] => "adipiscing \"elit"
            [5] => dolor
        )

)

보시다시피, 인용 된 문자열 내부의 탈출 된 인용문도 설명합니다.

편집하다

짧은 설명 :

"           # match the character '"'
(?:         # start non-capture group 1 
  \\        #   match the character '\'
  .         #   match any character except line breaks
  |         #   OR
  [^\\"]    #   match any character except '\' and '"'
)*          # end non-capture group 1 and repeat it zero or more times
"           # match the character '"'
|           # OR
\S+         # match a non-whitespace character: [^\s] and repeat it one or more times

그리고 일치하는 경우 %22 이중 인용문 대신 : 당신은 다음과 같습니다.

preg_match_all('/%22(?:\\\\.|(?!%22).)*%22|\S+/', $text, $matches);

다른 팁

이것은 훨씬 쉬웠을 것입니다 str_getcsv().

$test = 'Lorem ipsum "dolor sit amet" consectetur "adipiscing elit" dolor';
var_dump(str_getcsv($test, ' '));

당신을 준다

array(6) {
  [0]=>
  string(5) "Lorem"
  [1]=>
  string(5) "ipsum"
  [2]=>
  string(14) "dolor sit amet"
  [3]=>
  string(11) "consectetur"
  [4]=>
  string(15) "adipiscing elit"
  [5]=>
  string(5) "dolor"
}

이 다중 폭발 기능을 시도 할 수도 있습니다

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);

어떤 상황에서는 작은 알려진 token_get_all() 유용 할 수 있습니다 :

$tokens = token_get_all("<?php $text ?>");
$separator = ' ';
$items = array();
$item = "";
$last = count($tokens) - 1;
foreach($tokens as $index => $token) {
    if($index != 0 && $index != $last) {
        if(count($token) == 3) {
            if($token[0] == T_CONSTANT_ENCAPSED_STRING) {
                $token = substr($token[1], 1, -1);
            } else {
                $token = $token[1];
            }
        }
        if($token == $separator) {
            $items[] = $item;
            $item = "";
        } else {
            $item .= $token;
        }
    }
}

결과:

Array
(
    [0] => Lorem
    [1] => ipsum
    [2] => dolor sit amet
    [3] => consectetur
    [4] => adipiscing elit
    [5] => dolor
)

나는 이와 비슷한 복잡한 문자열 분할 문제와 함께 여기에 왔지만 여기서 답은 내가 원하는 것을 정확하게 수행하지 못했습니다. 그래서 나는 내 자신을 썼습니다.

다른 사람에게 도움이되는 경우를 대비하여 여기에 게시하고 있습니다.

이것은 아마도 매우 느리고 비효율적 인 방법 일 것입니다. 그러나 그것은 나에게 효과적입니다.

function explode_adv($openers, $closers, $togglers, $delimiters, $str)
{
    $chars = str_split($str);
    $parts = [];
    $nextpart = "";
    $toggle_states = array_fill_keys($togglers, false); // true = now inside, false = now outside
    $depth = 0;
    foreach($chars as $char)
    {
        if(in_array($char, $openers))
            $depth++;
        elseif(in_array($char, $closers))
            $depth--;
        elseif(in_array($char, $togglers))
        {
            if($toggle_states[$char])
                $depth--; // we are inside a toggle block, leave it and decrease the depth
            else
                // we are outside a toggle block, enter it and increase the depth
                $depth++;

            // invert the toggle block state
            $toggle_states[$char] = !$toggle_states[$char];
        }
        else
            $nextpart .= $char;

        if($depth < 0) $depth = 0;

        if(in_array($char, $delimiters) &&
           $depth == 0 &&
           !in_array($char, $closers))
        {
            $parts[] = substr($nextpart, 0, -1);
            $nextpart = "";
        }
    }
    if(strlen($nextpart) > 0)
        $parts[] = $nextpart;

    return $parts;
}

사용법은 다음과 같습니다. explode_adv 5 개의 인수를 가져옵니다.

  1. 블록을 여는 문자 배열 - 예를 들어 [, (, 등.
  2. 블록을 닫는 문자 배열 - 예를 들어 ], ), 등.
  3. 블록을 전환하는 캐릭터 배열 - 예 : ", ', 등.
  4. 다음 부분으로 분할 해야하는 문자 배열.
  5. 작업 할 문자열.

이 방법에는 아마도 결함이 있습니다. 편집은 환영합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top