【问题标题】:A good way to get the text between 2-3 sets of curly brackets [closed]在 2-3 组大括号之间获取文本的好方法 [关闭]
【发布时间】:2012-09-04 22:34:02
【问题描述】:

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

{我想要|我需要}造出这{愚蠢|真棒|恼人}的句子 {格式化{快速|快速}和随机|旋转和随机}

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

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

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

从最初的文本。

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

【问题讨论】:

  • 我从来没有见过这样的格式o.o你能用JSON或XMLRPC请求它吗?
  • 我以前见过这样的东西……
  • 啊哈! Link
  • 我{wondering|seeing}你可能在 {{{formatting{{{random|||spin}}} |随机|||旋转和随机}}} }

标签: php string random formatting


【解决方案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() 并将所有“逻辑”放在回调中,这样您就可以一次完成整个处理。

【讨论】:

    【解决方案2】:

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

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

    一个简单的例子

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

      • 你会在“{this|that} foo {this|that}”上失败。和重复......不确定较长文本的资源使用情况。 preg_replace_callback() 会更干净
      • 您的示例似乎有效:codepad.viper-7.com/FaOc9I
      猜你喜欢
      • 1970-01-01
      • 2019-03-18
      • 2015-01-28
      • 1970-01-01
      • 2011-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-25
      相关资源
      最近更新 更多