PHP wordwrap和非打印字符串
我卡住了,卡住了,卡住了 我正在编写一个需要方法的类,但我无法找到一个完全通过我编写的所有单元测试的解决方案,每个解决方案都有一些小问题 该方法正在包装文本(但带有catch),并具有三个参数:PHP wordwrap和非打印字符串,php,string,split,Php,String,Split,我卡住了,卡住了,卡住了 我正在编写一个需要方法的类,但我无法找到一个完全通过我编写的所有单元测试的解决方案,每个解决方案都有一些小问题 该方法正在包装文本(但带有catch),并具有三个参数: $text(需要进行单词包装的字符串) $width(要换行的宽度) $markup-一个标记字符串数组,可以在$text的不同位置随机放置在其中,并用于以后对文本进行样式化(因此被删除) 例如,如果有一组标记字符串[“!!”、“](它们可以是任何内容),并且文本“这是一个!!单词!!!这是一些水果
- $text(需要进行单词包装的字符串)
- $width(要换行的宽度)
- $markup-一个标记字符串数组,可以在$text的不同位置随机放置在其中,并用于以后对文本进行样式化(因此被删除)
[“!!”、“]
(它们可以是任何内容),并且文本“这是一个!!单词!!!这是一些水果。”
将其包装为25个字符的宽度:
1234567890123456789012345
This is a word and this
is some fruit.
这将是正确的包装,但为了让wordwrap工作,我必须删除标记并运行PHP的wordwrap(将\n适当地放入文本字符串中),然后返回标记以供以后处理
所以,问题是,作为最佳实践,我宁愿使用php的wordwrap函数,也不愿使用我自己的wordwrap函数。以下是我迄今为止尝试过的解决方案,但在小范围内未能通过单元测试:
- 将$markup字符串替换为“\a”(beep的转义序列-
使用我认为不会使用的字符),跟踪
其中$markup字符串位于单独数组中运行word wrap的位置,
然后将$markup字符串放回现在的wordwrapped字符串中
- 失败,因为wordwrap将\a计为一个字符,因此 标记,更糟糕的文字包装工作
- 将标记及其位置保留在一个单独的数组中,并尝试重新生成字符串
- 越来越好,但我存储的位置是相对的,这意味着当我开始恢复标记值时,字符串正在拉伸,位置值无效
//失败的测试用例套件的一部分:
$original=“这是!s!o!m!e文本。”;
$answer=$markup->stripMarkup($original);
$this->assertSame(“这是一些文本。”,$answer);
$answer=$markup->returnMarkup($answer);
$this->assertSame($original,$answer);
//phpunit故障
断言两个字符串相同失败。
期待:这是!s啊!M电子文本。
实际:这是一些文本。!!!!
越来越好,但我存储的位置是相对的,这意味着
当我开始恢复标记值时,字符串正在拉伸和移动
位置值无效
如果将它们存储在原始字符串中的绝对位置,则可以递归地(即每次更新新字符串后)将它们添加回原始位置。唯一需要说明的是
wordwrap
新增的\n
字符。假设原始字符串不包含任何换行符,则在插入时,您还可以计算插入位置之前出现的\n
的次数,并通过添加该数字重新计算其余的插入点。如果您在精彩的描述中包含一些代码,这会很有帮助。您是否考虑过使用或是,很遗憾,我没有保存这两个解决方案,因为我一直在尝试并继续前进……但如果这有帮助,我可以尝试重新创建。这两种解决方案都有一定的效果,也就是说,如果没有太多的标记,它就起作用了,并且会随着更多的标记而降级markup@JamieBicknell-谢谢你的链接,第一个链接很有趣,我会研究它,但是标记不必用括号括起来,就像htmlI不明白你如何对待字符串中的code>。它们已在wordwrap示例中消失。怎么了?答对了!我知道外面有些东西我就是看不见。我认为加价是个问题,但我也知道所有累计加价的长度。非常感谢。
// 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.!!!!