PHP自动换行和非打印字符串

时间:2016-06-29 14:36:41

标签: php string split

我被困住,卡住,卡住了。

我正在编写一个需要方法的类,我找不到完全通过我编写的所有单元测试的解决方案,每个解决方案都有小问题。

该方法包装文本(但有一个catch)并有三个参数:

  • $ text (需要自动换行的字符串)
  • $ width (要换行的宽度)
  • $ markup - 一系列标记字符串,可以在各个点随机放置在$ text内部,并将用于以后对文本进行样式化(并因此删除)。

例如,如果有一组标记字符串[“!!”,”<lime>”](它们可以是任何内容),并且文本“This is a !!word!!! and this is some <lime>fruit<lime>.”将其文字换行宽度为25个字符:

1234567890123456789012345
This is a word and this 
is some fruit.

这将是正确的包装,但为了使wordwrap工作,我必须删除标记并运行PHP的wordwrap(将文本字符串放入适当的文本字符串),然后返回用于以后处理的标记。

所以,这就是问题所在,我更倾向于使用php的wordwrap函数而不是使用自己的函数作为最佳实践。以下是我到目前为止尝试过的解决方案,但是在很小的方面未能通过单元测试:

  • 用'\ a'替换$ markup字符串(beep的转义序列 - 使用我认为不会使用的角色,跟踪 哪个$ markup字符串在一个单独的数组中运行,运行自动换行, 然后将$ markup字符串放回现在的wordwrapped字符串

    • 失败,因为wordwrap将\ a计为一个字符,因此更多 标记,更糟糕的wordwrap工作
  • 将标记及其位置数组保存在单独的数组中并尝试重建字符串

    • 变得更好,但我存储的位置是相对的,这意味着当我开始恢复标记值时,字符串会拉伸并且位置值无效

我开始沿着保留两根弦的道路,剥离和原始,然后沿着每个弦向下行进以重建原始,但这似乎......丑陋。这让我相信我一定会错过一些东西。

有什么想法吗?

以下是剥离和替换的第二个解决方案辅助函数:

/ **  *获取文本并替换所有标记并存储标记和  *他们在markupInText中的位置供以后使用  *  * @param $ text  * @return string - 将所有标记切换为/ a的文本  * / public function stripMarkup($ text){

// if there are any markups
if ($this->markupStyles) {


    // get all the markups
    $markups = array_keys($this->markupStyles);

    // go through each markup
    foreach ($markups AS $nextMarkup) {

        // search through the string
        $offset = 0;

        // search for the next markup
        while (($pos = strpos($text, $nextMarkup, $offset)) !== false) {

            // add the position to the array of position for the markup
            $this->markupInText[$nextMarkup][] = $pos;

            // move the offset as far as the next markup
            $offset = $pos + strlen($nextMarkup);
        }
    }

    // strip out the markup
    foreach ($markups AS $nextMarkup) {

        // replace each string with blank
        $text = str_replace($nextMarkup,"",$text);
    }
}

return $text;

}

/**
 * Return the markup that was stripped of markup to its former glory
 * @param $text
 * @return string - the restored text
     */

public function returnMarkup($text) {


// go through each markup
foreach ($this->markupInText AS $markup => $posArray) {

    // go through the range of positions
    foreach ($posArray AS $pos) {

        // put back the markup
        $text = substr($text,0,$pos) . $markup . substr($text,$pos);

    }


}

// reset the markup in text
$this->markupInText = [];

// return the restored text
return $text;

}

// part of the suite of test cases that fails:

        $original = "This<red> is<red> !s!o!m!e text.";
        $answer = $markup->stripMarkup($original);
        $this->assertSame("This is some text.",$answer);
        $answer = $markup->returnMarkup($answer);
        $this->assertSame($original, $answer);

// phpunit failure
Failed asserting that two strings are identical.
Expected :This<red> is<red> !s!o!m!e text.
Actual   :This <red>is <red>some text.!!!!

1 个答案:

答案 0 :(得分:1)

  

变得更好,但我存储的位置是相对的,意思是   当我开始恢复标记值时,字符串是拉伸的   位置值无效

如果将它们存储在原始字符串中的绝对位置,则可以递归(即每次更新新字符串后)将它们添加回原始位置。您唯一需要考虑的是\n新添加的wordwrap个字符。假设原始字符串不包含任何换行符,在插入时,您还可以计算\n个出现次数,直到您插入的位置并重新计算其余插入点通过添加该号码。