3

我正在使用一个返回以下格式文本的 API:

{我想要|我需要}制作这个{愚蠢|真棒|刺激}句子{格式化{快速|快速}和随机|旋转和随机}

使用 PHP,我需要像这样格式化字符串:

"I need to make this irritating sentence formatting quickly";

或者

"I want to make this awesome sentence spin and be random";

从最初的文本。

如果大括号不能包含另一组大括号,我不会有问题。有什么建议或任何代码可以帮助我解决这个问题吗?

4

3 回答 3

1

我假设你的源字符串是这样的:

{I want|I need} to make this {stupid|awesome|irritating}
sentence formatting {rapidly|quickly} and {random|spin and be random} 

否则括号是嵌套的,并且您的输出示例与您将它们放在源字符串中的方式不匹配。然后preg_match_all()像这样使用:

preg_match_all("/{.*}/U",$sourceString, $result, 
                      PREG_PATTERN_ORDER|PREG_OFFSET_CAPTURE);

这对你$sourceString来说会产生:

array(1) {
  [0]=>
  array(4) {
    [0]=>
    array(2) {
      [0]=>
      string(15) "{I want|I need}"
      [1]=>
      int(0)
    }
    [1]=>
    array(2) {
      [0]=>
      string(27) "{stupid|awesome|irritating}"
      [1]=>
      int(29)
    }
    [2]=>
    array(2) {
      [0]=>
      string(17) "{rapidly|quickly}"
      [1]=>
      int(77)
    }
    [3]=>
    array(2) {
      [0]=>
      string(27) "{random|spin and be random}"
      [1]=>
      int(99)
    }
  }
}

你得到所有的物品。然后你可以处理每个条目,去掉“{”和“}”,explode()在“|”上 获得一系列可供选择的选项。然后你选择你想要的并用它替换以前找到的项目。请注意,我捕获了找到匹配模式的偏移量,因为您最终不能这样做,str_replace()因为我假设您希望能够在许多地方使用相同的条目(即“{this|that} foo {this|that}” str_replace()。替换两者,而我认为这是不需要的。所以我们在字符串中得到了偏移量,可以轻松计算字符串的长度,但这足以进行一些手术,并切断我们的条目并进行替换。其他更清洁的方法是使用preg_replace_callback()并把所有的“逻辑”

于 2012-09-11T23:17:31.597 回答
0

这可能不是几行代码就能完成的。因为你有嵌套代码,你甚至不能使用正则表达式来正确解析输入。

我的一个简单想法是将输入转换为 XML 并使用 SimpleXML 类来解析输入并在此基础上构建一个可以轻松转换为您想要的输出的 AST。

一个简单的例子

$xml = "<root>" .
        str_replace(
                array("{", "}"),
                array("<t>", "</t>"),
                $input) . 
        "</root>";

$dom = new SimpleXMLElement($xml);
//...
于 2012-09-11T23:25:30.903 回答
0

好的,这基于您提供的句子,但我会在投入生产之前对其进行更多测试。(例如,您不能有任何其他{,}|

http://codepad.viper-7.com/HpJKOt

<?php

$string = "{I want|I need} to make this {stupid|awesome|irritating} sentence {formatting {rapidly|quickly} and random|spin and be random}";

echo parseString($string);

function parseString($string) {

    // look for {abc|def}
    if (preg_match_all("/\{(([^\{\|\}]*)\|)+([^\{\|\}]*)\}/", $string, $matches, PREG_OFFSET_CAPTURE)) {

        // trim {} and put into array
        $options = explode('|', substr($matches[0][0][0], 1, -1));

        // randomize
        shuffle($options);

        // make the replacement
        $string = str_replace($matches[0][0][0], $options[0], $string);

        // check again
        return parseString($string);
    }

    return $string;
}
于 2012-09-12T00:08:55.987 回答