PHP preg_split如果不在花括号内

时间:2009-08-29 17:52:08

标签: php regex programming-languages preg-split

我是一个使用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. #00AA00
  7. 或者
  8. 字体
  9. Arial Black
  10. 摩纳哥
  11. ,其中
  12. 两个
  13. 颜色
  14. 字体
  15. 确定
  16. 随机
  17. (花括号内的字符串显示在粗体中) 大括号内的字符串必须是每个元素。所以{Hello,World!}不能是:  你好,  2.世界!

    我该怎么做?

    提前致谢。

5 个答案:

答案 0 :(得分:5)

使用这样的东西怎么样:

$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也会起作用; - )

答案 1 :(得分:0)

订单是否重要?如果没有,你可以提取所有{},删除它们,然后对剩余的字符串进行操作。

答案 2 :(得分:0)

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

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

答案 3 :(得分: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;
        }
    }
}
?>

代码未经测试。

答案 4 :(得分:0)

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

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

代码:(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。您可以使用强标签替换大括号,例如:https://3v4l.org/fXrgE

p.p.s。您可以使用preg_replace_callback()构建精确的有序列表:(Demo)<-转移到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>";