2

我正在使用 PHP 制作脚本语言解释器。我有这个脚本语言的代码:

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

(是的,很难相信,但这就是语法)

我必须使用哪个正则表达式来分割它(用空格分割),但前提是不在大括号内。所以我想把上面的代码变成这个数组:

  1. 你好世界!
  2. 任何一个
  3. 颜色
  4. 蓝色的
  5. 或者
  6. 红色的
  7. 或者
  8. #00AA00
  9. 任何一个
  10. 字体
  11. 宋体黑
  12. 或者
  13. 摩纳哥
  14. 在哪里
  15. 两个都
  16. 颜色
  17. 字体
  18. 决定
  19. 随机

(大括号内的字符串在上面以粗体显示)大括号内的字符串每个必须是一个元素。所以 {Hello, World!} 不能是:1. Hello, 2. World!

我怎样才能做到这一点?

提前致谢。

4

5 回答 5

6

使用这样的东西怎么样:

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

这会让你:

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)

的,你只需要迭代这些结果;以 { 开头并以 } 结尾的将是您的“重要”词,其余的将是其他词。


评论后编辑:识别重要单词的一种方法是这样的:

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

或者,就像你说的,使用 strpos 和 strlen 也可以;-)

于 2009-08-29T18:03:32.687 回答
0

顺序重要吗?如果不是,您可以提取所有 {},删除它们,然后对剩余的字符串进行操作。

于 2009-08-29T17:59:08.780 回答
0

我会使用preg_replace_callback替换它们。通过回调,您可以跟踪订单并将其替换为 %var1%、%var2% 等。

我不认为有一种方法可以通过空格来爆炸,但不是在大括号中而不事先修改字符串。

于 2009-08-29T18:03:39.003 回答
0

这可以在没有正则表达式的情况下迭代完成。您遍历整个字符串。你把每个字符都放在一个临时变量中,除非你找到一个空格。找到空格后,将临时变量的内容放入数组中,清空,然后继续。

如果找到括号,则设置一个布尔值,然后将所有内容放入 temp var,直到找到右括号。等等。

<?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;
        }
    }
}
?>

代码未经测试。

于 2009-08-29T18:05:25.273 回答
0

您想在大括号中不包含的所有空格上进行拆分。

匹配卷曲表达式或一系列非空白字符,然后忽略这些匹配项,\K然后使用以下空格作为分隔符。

代码:(演示

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

ps您可以用这样的强标签替换花括号:https ://3v4l.org/fXrgE

pps 您可以使用以下命令构建您的确切排序列表preg_replace_callback():(演示)<--转移到 phptester.net 以查看它的呈现

$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>";
于 2018-12-20T23:48:58.690 回答