我的代码有问题,我不明白。 有人可以帮忙吗?
$query="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
$seq=chunk_split($query,50,"<br />");
$truecol = "<span style=\"color: hsl(0,100%,25%);\">";
function colorSequence ($seq,$position,$truecol,$TFBSlength){
$nucleotides = str_split($seq);
foreach ($nucleotides as $index => $nucl){
if ($index == $position){
echo $truecol;
}
if ($index == $position + $TFBSlength){
echo "</span>";
}
echo $nucl;
}
echo "\n";
}
colorSequence($seq,49,$truecol,1);
?>
这是我的代码。基本上我把输出代码看起来像这样:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA(red)A(/red)
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
当我运行函数colorSequence($seq,49,$truecol,1);
时它会这样做
但是,如果我运行colorSequence($seq,49,$truecol,3);
我得到这个:
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA< span="">r />AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC<>
(来自字母49的所有字母都是红色的,即使我只想要从49到51的3个字母变成红色)。
有人可以解决这个问题吗?
答案 0 :(得分:2)
如果你print_r($nucleotides)
,你会看到
Array
(
......
[49] => A
[50] => <
[51] => b
[52] => r
[53] =>
......
)
所以你要将<span>
插入到<br />
中,这会破坏以下的HTML ...
答案 1 :(得分:2)
$query="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
$seq=chunk_split($query,50,'');
$truecol = "<span style=\"color: hsl(0,100%,25%);\">";
function colorSequence ($seq,$position,$truecol,$TFBSlength){
$nucleotides = str_split($seq);
foreach ($nucleotides as $index => $nucl){
if ($index == $position){
echo $truecol;
}
if ($index == $position + $TFBSlength){
echo "</span>";
}
if(($index%50)==0){
echo '<br>';
}
echo $nucl;
}
echo "\n";
}
colorSequence($seq,49,$truecol,1);
echo '<hr>';
colorSequence($seq,49,$truecol,3)
答案 2 :(得分:1)
您的函数添加的span标记会破坏chunk_split
创建的HTML。
答案 3 :(得分:0)
当您修改DNS字符串$query
时,您需要区分核苷酸的位置和一般的字符串偏移。
虽然起初两者相同,但是你添加到字符串的次数越多,它就越多。
如果你将字符串封装到它自己的对象中来处理HTML标记并且不计算它们(包括标记周围的空白区域),那么事情就会变得容易了:
$query = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
// wrap line: 11 lines à 50 nucleotids
$seq = chunk_split($query, 50, "<br />\n");
// get help from sequence object
$sequence = new AmendSequence($seq);
// some HTML comments for demonstration purposes
$sequence->insertAt(0, "<!-- first line -->\n");
$sequence->insertAt(50, "<!-- second line -->\n", TRUE); # TRUE: Place after <br />
$sequence->insertAt(75, "<!-- inside second line -->");
$sequence->insertAt(550, "<!-- at end -->", TRUE); # TRUE: Place after <br />
// colorize
$color = '<span style="color: hsl(0,100%,25%);">';
$sequence->insertAt(49, $color);
$sequence->insertAt(50, '</span>');
printf("Sequence with %d nucleotids:\n", count($sequence)); # count gives length w/o amends
echo $sequence, "\n"; # that prints your sequence with all amends
创建以下输出:
Sequence with 550 nucleotids:
<!-- first line -->
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<span style="color: hsl(0,100%,25%);">A</span><br />
<!-- second line -->
AAAAAAAAAAAAAAAAAAAAAAAAA<!-- inside second line -->AAAAAAAAAAAAAAAAAAAAAAAAA<br />
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA<br />
AAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB<br />
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB<br />
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB<br />
BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCC<br />
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC<br />
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC<br />
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC<br />
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC<br />
<!-- at end -->
所以这里的实际魔法是insertAt
方法,它接受nucledotide的偏移位置并计算它的字符串偏移量。它全部封装在一个自己的类中,一开始可能有点过多,但实际操作是将包含DNA和HTML的字符串分成仅DNS的分区并获取它们的实际字符串偏移量。完整的源代码:
<?php
/**
* @link http://stackoverflow.com/questions/10446162/how-to-wordwrap-with-different-length-string-modification
*/
/**
* Treat text with "tags" as text without tags when insertAt() is called.
*/
class AmendSequence implements IteratorAggregate, Countable
{
/**
* regex pattern for a tag
*/
const TAG = '\s*<[^>]*>\s*';
/**
* @var string
*/
private $query;
/**
* @param string $query
*/
public function __construct($query = '')
{
$this->setQuery($query);
}
/**
* @param int $offset
* @param string $string
* @param bool $after (optional) prefer after next tag instead before
*/
public function insertAt($offset, $string, $after = FALSE)
{
$offset = $this->translate($offset, $after);
$this->query = substr_replace($this->query, $string, $offset, 0);
}
/**
* Translate virtual offset to string offset
* @param int $virtualOffset
* @return int
* @throws InvalidArgumentException
*/
public function translate($virtualOffset, $after)
{
if ($virtualOffset < 0) throw new InvalidArgumentException(sprintf('Offset can not be lower than 0, is %d.', $virtualOffset));
$virtualCurrent = 0;
foreach ($this as $segment) {
list(, $current, $length) = $segment;
$delta = ($virtualOffset - $virtualCurrent) - $length;
if ($delta < 0 || ($delta === 0 && !$after)) {
return $current + $length + $delta;
}
$virtualCurrent += $length;
}
if ($virtualCurrent === $virtualOffset && $after) {
return strlen($this->query);
}
throw new InvalidArgumentException(sprintf('Offset can not be larger than %d, is %d.', $virtualCurrent, $virtualOffset));
}
/**
* @return array
*/
public function getSegments()
{
$segments = preg_split('/' . self::TAG . '/', $this->query, 0, PREG_SPLIT_OFFSET_CAPTURE | PREG_SPLIT_NO_EMPTY);
foreach ($segments as &$segment) {
$segment[2] = strlen($segment[0]);
}
return $segments;
}
public function getSequence()
{
$buffer = '';
foreach ($this as $segment) {
$buffer .= $segment[0];
}
return $buffer;
}
/**
* @return string
*/
public function getQuery()
{
return $this->query;
}
/**
* @param string $query
*/
public function setQuery($query)
{
$this->query = (string)$query;
}
/**
* Retrieve an external iterator
* @link http://php.net/manual/en/iteratoraggregate.getiterator.php
* @return Traversable An instance of an object implementing <b>Iterator</b> or <b>Traversable</b>
*/
public function getIterator()
{
return new ArrayIterator($this->getSegments());
}
/**
* @link http://php.net/manual/en/countable.count.php
* @return int The custom count as an integer.
*/
public function count()
{
$length = 0;
foreach ($this as $segment) {
$length += $segment[2];
}
return $length;
}
/**
* @return string
*/
public function __toString()
{
return $this->query;
}
}
$query = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC";
// wrap line: 11 lines à 50 nucleotids
$seq = chunk_split($query, 50, "<br />\n");
// get help from sequence object
$sequence = new AmendSequence($seq);
// some HTML comments for demonstration purposes
$sequence->insertAt(0, "<!-- first line -->\n");
$sequence->insertAt(50, "<!-- second line -->\n", TRUE); # TRUE: Place after <br />
$sequence->insertAt(75, "<!-- inside second line -->");
$sequence->insertAt(550, "<!-- at end -->", TRUE); # TRUE: Place after <br />
// colorize
$color = '<span style="color: hsl(0,100%,25%);">';
$sequence->insertAt(49, $color);
$sequence->insertAt(50, '</span>');
printf("Sequence with %d nucleotids:\n", count($sequence)); # count gives length w/o amends
echo $sequence, "\n"; # that prints your sequence with all amends
echo $sequence->getSequence(); # without the amends
现在随意为任意多个部分着色 - 无论是否已有序列内的其他HTML。