Domanda

Sono makin' un interprete del linguaggio di scripting PHP. Ho questo codice in linguaggio di scripting che:

write {Hello, World!} in either the color {blue} or {red} or {#00AA00} and in either the font {Arial Black} or {Monaco} where both the color and the font are determined randomly

(Sì, è difficile da credere, ma che è la sintassi)

Quali regex devo usare per dividere questo (split da spazi), ma solo se non all'interno delle parentesi graffe. Quindi voglio girare il codice sopra in questo array:

  1. scrittura
  2. Ciao, mondo!
  3. in
  4. o
  5. il
  6. color
  7. blu
  8. o
  9. rossa
  10. o
  11. # 00AA00
  12. e
  13. in
  14. o
  15. il
  16. carattere
  17. Arial Black
  18. o
  19. Monaco
  20. dove
  21. sia
  22. il
  23. color
  24. e
  25. carattere
  26. sono
  27. determinato
  28. in modo casuale

(Le stringhe all'interno delle parentesi graffe sono esposizione qui sopra in grassetto ) Le stringhe all'interno delle parentesi graffe devono essere un elemento ciascuno. Così {! Ciao, Mondo} non può essere:  1. Ciao,  2. World!

Come posso fare questo?

Grazie in anticipo.

È stato utile?

Soluzione

Cosa succede ad usare qualcosa di simile a questo:

$str = 'write {Hello, World!} in either the color {blue} or {red} or {#00AA00} and in either the font {Arial Black} or {Monaco} where both the color and the font are determined randomly';

$matches = array();
preg_match_all('#\{.*?\}|[^ ]+#', $str, $matches);

var_dump($matches[0]);

che vi consentiranno di:

array
  0 => string 'write' (length=5)
  1 => string '{Hello, World!}' (length=15)
  2 => string 'in' (length=2)
  3 => string 'either' (length=6)
  4 => string 'the' (length=3)
  5 => string 'color' (length=5)
  6 => string '{blue}' (length=6)
  7 => string 'or' (length=2)
  8 => string '{red}' (length=5)
  9 => string 'or' (length=2)
  10 => string '{#00AA00}' (length=9)
  11 => string 'and' (length=3)
  12 => string 'in' (length=2)
  13 => string 'either' (length=6)
  14 => string 'the' (length=3)
  15 => string 'font' (length=4)
  16 => string '{Arial Black}' (length=13)
  17 => string 'or' (length=2)
  18 => string '{Monaco}' (length=8)
  19 => string 'where' (length=5)
  20 => string 'both' (length=4)
  21 => string 'the' (length=3)
  22 => string 'color' (length=5)
  23 => string 'and' (length=3)
  24 => string 'the' (length=3)
  25 => string 'font' (length=4)
  26 => string 'are' (length=3)
  27 => string 'determined' (length=10)
  28 => string 'randomly' (length=8)

Il, è sufficiente iterare su tali risultati; quelli a partire da {e terminano da} saranno le tue parole "importanti", e gli altri saranno il resto.


Modifica al termine il commento: un modo per identificare le parole importanti sarebbe qualcosa di simile:

foreach ($matches[0] as $word) {
    $m = array();
    if (preg_match('#^\{(.*)\}$#', $word, $m)) {
        echo '<strong>' . htmlspecialchars($m[1]) . '</strong>';
    } else {
        echo htmlspecialchars($word);
    }
    echo '<br />';
}

In alternativa, come hai detto tu, lavorando con strpos e strlen avrebbe funzionato troppo; -)

Altri suggerimenti

Ha l'ordine importa? Se non si poteva estrarre tutti {} s ', rimuoverli, quindi operare sulla corda avanzi.

Vorrei sostituirli utilizzando preg_replace_callback . Con la richiamata è possibile tenere traccia dell'ordine e sostituirli con qualcosa come% var1%,% var2%, ecc.

Non credo che ci sia un modo per esplodere da spazi, ma non nelle parentesi graffe senza modificare la stringa in anticipo.

Ciò potrebbe essere fatto senza iterately regexp. Di eseguire iterazioni su l'intera stringa. Hai messo ogni personaggio in una variabile temporanea, a meno che non si trova uno spazio. Quando si trova uno spazio, si mette il contenuto della variabile temporanea nella matrice, svuotarlo, e poi continuare.

Se si trova una staffa, si imposta un valore booleano, e poi mettere tutto in temp var, fino a trovare una parentesi di chiusura. E così via.

<?php
$string = "write {Hello, World!} in either the color {blue} or {red} or {#00AA00} and in either the font {Arial Black} or {Monaco} where both the color and the font are determined randomly";
$bracket = false;
$words = array();
$temp = "";

for($i = 0; $i < strlen($string); $i++){    
    $char = $string[$i]
    if($bracket){
        $temp .= $char;
        if($char == "}"){
            $bracket = false;
            $words[] = $temp;
        }
    }
    else{
        if($char == " "){
            if($temp != ""){
                $words[] = $temp;
                $temp = "";
            }
        }
        elseif($char == "{"}{
            $temp .= $char;
            $bracket = true;
        }
        else{
            $temp .= $char;
        }
    }
}
?>

Codice è testato.

Si desidera dividere in tutti gli spazi che non sono contenuti all'interno di parentesi graffe.

Abbinare le espressioni ricci o una sequenza di caratteri che non sono spazi quindi ignorare queste partite con \K quindi utilizzare il seguente spazio come delimitatore.

Codice: ( Demo )

$text = 'write {Hello, World!} in either the color {blue} or {red} or {#00AA00} and in either the font {Arial Black} or {Monaco} where both the color and the font are determined randomly';

var_export(preg_split('~({[^}]*}|\S+)\K ~', $text));

P.S. È possibile sostituire le parentesi graffe con forti tag come questo: https://3v4l.org/fXrgE

p.p.s. Si potrebbe costruire la vostra lista ordinata esatto con preg_replace_callback(): ( Demo ) <- trasferimento in phptester.net per vederlo reso

$text = 'write {Hello, World!} in either the color {blue} or {red} or {#00AA00} and in either the font {Arial Black} or {Monaco} where both the color and the font are determined randomly';

echo "<ol>" , preg_replace_callback('~{([^}]*)}|(\S+)~', function($m) {
        if (!isset($m[2])) {
            return "<li><strong>{$m[1]}</strong></li>\n";
        }
        return "<li>{$m[2]}</li>\n";
    },
    $text) , "<ol>";
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top