2009-06-24 19 views
2

Ich habe den folgenden CodeExtract Schlüsselwörter/Tags aus Zeichenfolge mit preg_match_all

$str = "keyword keyword 'keyword 1 and keyword 2' another 'one more'".'"another keyword" yes,one,two'; 

preg_match_all('/"[^"]+"|[^"\' ,]+|\'[^\']+\'/', $str, $matches); 

echo "<pre>"; print_r($matches); echo "</pre>"; 

Wo ich es will Schlüsselwörter aus einer Zeichenfolge extrahieren und zusammen halten diejenigen, eingewickelt in einfachen oder doppelten Anführungszeichen, diese oben genannte Code OK funktioniert , aber es gibt die Werte mit den Anführungszeichen zurück. Ich weiß, dass ich diese über str_replace oder ähnliches entfernen kann, aber ich suche wirklich nach einer Möglichkeit, dies über die Funktion preg_match_all zu lösen.

Ausgang:

Array 
(
    [0] => Array 
     (
      [0] => keyword 
      [1] => keyword 
      [2] => 'keyword 1 and keyword 2' 
      [3] => another 
      [4] => 'one more' 
      [5] => "another keyword" 
      [6] => yes 
      [7] => one 
      [8] => two 
     ) 

) 

Außerdem glaube ich, meine regex ein wenig kitschig sein, also irgendwelche Vorschläge für eine bessere wäre würde :)

Irgendwelche Vorschläge/Hilfe geschätzt würde sehr gut sein.

+0

Was ist so etwas wie 'a, "b", c, d, "e"' oder ' "b '"'" c'' – Gumbo

Antwort

1

Sie fast es haben; Sie müssen nur lookarounds verwenden, um die Zitate entsprechen:

'/(?<=\')[^\'\s][^\']*+(?=\')|(?<=")[^"\s][^"]*+(?=")|[^\'",\s]+/' 
+0

Hervorragend !!!!! Genau das habe ich gebraucht! Vielen Dank Alan M. Habe gerade versucht, die Regex zu verstehen, die Sie verwendet haben, und es beginnt, Sinn zu ergeben. Um ehrlich zu sein, ich bin nie auf das = vorher gestoßen.Nochmals vielen Dank, wirklich zu schätzen es –

+0

Sie möchten dies lesen: http://www.regular-expressions.info/lookaround.html Diese ganze Website ist ausgezeichnet. –

0

Werfen Sie einen Blick auf this tokenizeQuote function in den Kommentaren zu strtok function.

bearbeiten Sie müssen die Funktion ändern, da das Original funktioniert nur mit doppelten Anführungszeichen:

function tokenizeQuoted($string) 
{ 
    for ($tokens=array(), $nextToken=strtok($string, ' '); $nextToken!==false; $nextToken=strtok(' ')) { 
     $firstChar = $nextToken{0}; 
     if ($firstChar === '"' || $firstChar === "'") { 
      $nextToken = $nextToken{strlen($nextToken)-1} === $firstChar 
       ? substr($nextToken, 1, -1) 
       : substr($nextToken, 1) . ' ' . strtok($firstChar); 
     } 
     $tokens[] = $nextToken; 
    } 
    return $tokens; 
} 

bearbeiten Vielleicht sollten Sie einfach Ihren eigenen Parser schreiben:

$tokens = array(); 
$buffer = ''; 
$quote = null; 
$len = strlen($str); 
for ($i=0; $i<$len; $i++) { 
    $char = $str{$i}; 
    if ($char === '"' || $char === "'") { 
     if ($quote === null) { 
      if ($buffer !== '') { 
       $tokens[] = $buffer; 
       $buffer = ''; 
      } 
      $quote = $char; 
      continue; 
     } 
     if ($quote == $char) { 
      $tokens[] = $buffer; 
      $buffer = ''; 
      $quote = null; 
      continue; 
     } 
    } else if ($char === ',' || $char === ' ') { 
     if ($quote === null) { 
      if ($buffer !== '') { 
       $tokens[] = $buffer; 
       $buffer = ''; 
      } 
      continue; 
     } 
    } 
    $buffer .= $char; 
} 
if ($buffer !== '') { 
    $tokens[] = $buffer; 
} 
+0

Nicht ganz was ich suche, wie ich es mit preg_match_all machen möchte, aber danke (auch funktioniert die Funktion nicht mit einfachen Anführungszeichen) –

+0

Aber wieder berücksichtigt es Kommas wie meine Regex nur nicht Ich bin davon überzeugt, dass der beste Weg wäre, preg_match_all zu verwenden, aber wenn es nicht möglich ist, werde ich mich mit einem Ersatz begnügen. –

1
preg_match_all('/"([^"]+)"|[^"\' ,]+|\'([^\']+)\'/',$str,$matches); 

und verwenden Sie $matches[1] und $matches[2].

+0

Es müsste sein: preg_match_all ('/ "([^" ] +) "| ([^" \ ',] +) | \' ([^ \ '] +) \'/', $ str, $ Treffer); und verwenden Sie $ matches [1], $ matches [ 2] und $ Übereinstimmungen [3], die nach dem preg_match_a wiederum mehr Manipulation erfordern würden ll-Funktion, so dass es einfacher wäre, eine str_replace-Funktion array_map zuzuordnen, die die aktive Instanz des Arrays in ein Array zusammenführt. –

+0

Wie würden Sie vorschlagen, dass Sie die verschiedenen Ergebnisreihen zusammenfügen? –

+0

Es gibt keine native Kollationierungs-Array-Merge-Funktion, also würde ich eine schreiben, nehme ich an. Ich verstehe nicht ganz, was Ihre Leistungsanforderungen sind, daher ist es schwer zu sagen, was am besten geeignet ist. – chaos

0

erfordert dies eine einfache Funktion zu bekommen, was Sie wollen, aber es funktioniert

preg_match_all('/"([^"]+)"|([^"\' ,]+)|\'([^\']+)\'/',$str,$matches); 
function r($str) { 
    return str_replace(array('\'','"'), array(''), $str); 
} 
$a = array_map('r', $matches[0]); 
print_r($a); 
+0

Danke, das habe ich mir schon mal angeschaut aber es entsteht unnötige Arbeitsbelastung. Vielen Dank für Ihre Eingabe obwohl Galen –

Verwandte Themen