正则表达式嵌套该如何匹配?以及更多

tinyfool 发布于 2013年12月28日 | 更新于 2013年12月28日
无人欣赏。

我今天开始在StackOverflow的Careers上尝试应聘一些Remote的工作,遇到一道笔试题。

Code a simple Random Sentence Spinning Function(s) Or Class.

Basically you take this following variable Where the | is a delimiter
meaning either word could be shown up:

$rand_sentence = "{Please|Just} make this {cool|awesome|random} test sentence
{rotate {quickly|fast} and random|spin and be random}";

and the end result should be an output of the sentence like:
Please make this cool test sentence rotate fast and random.
OR
Just make this random test sentence spin and be random.
or any other random variation...

然后我就搜索了下“正则表达式嵌套该如何匹配”,找到了一个解决方案,$patten = '/{(?:[^{}]+|(?R))*}/';,然后写了一个程序。

<?php
$rand_sentence = "{Please|Just} make this {cool|awesome|random} test sentence
{rotate {quickly|fast} and random|spin and be random}";
$patten = '/{(?:[^{}]+|(?R))*}/';

echo randspin($rand_sentence);

function randspin($sentence) {
  global $patten;
  return preg_replace_callback($patten, "randpick",$sentence);
}

function randpick($input) {
  global $patten;
  $line = $input[0];
  $line = substr($line,1,strlen($line)-2);
  $matchCount = preg_match_all($patten,$line,$matches);
  if($matchCount>0) {
    return randspin($line);
  }else {

    $parts = explode("|",$line);
    $index = rand(0,count($parts));
    return $parts[$index];
  }
}

代码提交以后,我才发现我的解有点问题,可以匹配简单的{Please|Just}问题以及{rotate {quickly|fast} and be random}问题,但是random|spin这样的外面没有{}的解决不了,而按照题目的要求其实也是要能解决的。

大家看该如何解决?我尝试了几个写法都不对。

共7条回复
tinyfool 回复于 2013年12月28日

原来是起太早,脑子还不清醒,一会儿改

ibone 回复于 2013年12月28日

js的解决方案


        var replace = function(str){
            str = str.replace(/{[^{}]+}/g,function(substr){
                var strarr = substr.replace(/[{}]/g,'').split('|');
                return strarr[Math.floor(Math.random()*strarr.length)];
            });
            if(/{[^{}]+}/.test(str)){
                return replace(str);
            }else{
                return str;
            }
        }

tinyfool 回复于 2013年12月28日

脑子被绕糊涂了,看样子还是年纪大了,哈哈

ibone 回复于 2013年12月28日

奇怪str_arr这个变量的下划线会被替换掉

ibone 回复于 2013年12月28日

解决思路: 先解决{ }内没有嵌套{ }的组合,随机选择字符替换后,return 出来的字符串如果还包含 { },那么递归

tinyfool 回复于 2013年12月28日

好吧,改好了

<?php
$rand_sentence = "{Please|Just} make this {cool|awesome|random} test sentence
{rotate {quickly|fast} and random|spin and be random}";

$patten = '/{(?:[^{}]+|(?R))*}/';

echo randspin($rand_sentence);
echo "\r\n";

function randspin($sentence) {
  global $patten;
  $ret = preg_replace_callback($patten, "randpick",$sentence);
  return $ret;
}

function randpick($input) {
  global $patten;
  $line = $input[0];
  if(substr($line,0,1)=="{")
    $line = substr($line,1);
  if(substr($line,-1)=="}")
    $line = substr($line,0,-1);

  $line = preg_replace_callback($patten, "randpick",$line);

  $parts = explode("|",$line);
  $index = rand(0,count($parts)-1);
    $ret = $parts[$index];
    return $ret;
}
tinyfool 回复于 2013年12月28日

5楼 @ibone 你的js代码我懒得研究了,哈哈

登录 或者 注册