我卡住了,卡住了,卡住了。
我正在写一个需要一个方法的类,我找不到一个完全通过我写的所有单元测试的解决方案,每个解决方案都有一些小问题。
该方法正在换行文本(但带有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(它将'n适当地放入文本字符串中),然后返回标记以供稍后处理。
所以,这里是问题,我宁愿使用php的wordwrap函数,而不是滚动我自己的,作为最佳实践。以下是我到目前为止尝试过的解决方案,但在单元测试中失败了:将$标记字符串替换为' 'a ' (beep -的转义序列)使用我认为不会使用的字符),跟踪在一个单独的数组中,运行自动换行,然后将$标记字符串放回现在带文字包装的字符串
中- 失败,因为换行将'a视为一个字符,因此更多
将标记及其位置保存在一个单独的数组中,并尝试重建字符串
- 越来越好,但我存储的位置是相对的,这意味着当我开始恢复标记值时,字符串正在拉伸,位置值无效
我开始保留两根弦,剥离的和原始的,然后沿着每根弦重建原始的,但这看起来……很丑。这让我相信我一定错过了什么。
任何想法?
下面是用于剥离和替换的第二个解决方案辅助函数:/* **获取文本并替换所有标记,并存储标记和*它们在markupInText中的位置供以后使用** @param $text* @返回字符串-文本与所有标记切换到/a*/{
// 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.!!!!
越来越好了,但是我存储的位置是相对的,意思是当我开始恢复标记值时,字符串正在拉伸和位置值无效
如果您将它们存储在原始字符串中的绝对位置,那么您可以递归地(即每次更新新字符串后)将它们添加回原始位置。你唯一需要考虑的是wordwrap
新增的'n
字符。假设原始字符串不包含任何换行字符,在插入时,您还将计算'n
s出现的次数,直到您要插入的位置,并通过添加该数字重新计算其余的插入点。