先抓后抓<;李>;内部php变量

先抓后抓<;李>;内部php变量,php,html,regex,parsing,dom,Php,Html,Regex,Parsing,Dom,或者,您可以在CSS中使用“#menu li:last child”而不是类名,这样您就不必修改PHP代码。DOM解决方案 <ul id="menu"> <li id="some_id" class="some_class">...</li> <li id="some_id" class="some_class">...</li> <li id="some_id" class="some_class my_class">..

或者,您可以在CSS中使用“
#menu li:last child
”而不是类名,这样您就不必修改PHP代码。

DOM解决方案

<ul id="menu">
<li id="some_id" class="some_class">...</li>
<li id="some_id" class="some_class">...</li>
<li id="some_id" class="some_class my_class">...</li>
</ul>
如果您知道HTML是有效的,也可以使用
loadXML
。这将使DOM不会添加HTML框架。请注意,然后必须将XPath更改为
'/ul/li[last()]/@class'

如果您不熟悉XPath查询,还可以使用常规DOM接口,例如

$dom = new DOMDocument;
$dom->loadHTML( $ul );
$xPath = new DOMXPath( $dom );
$xPath->query( '/html/body/ul/li[last()]/@class' )
      ->item( 0 )
      ->value .= ' myClass';

echo $dom->saveXml( $dom->getElementById( 'menu' ) );

编辑由于您现在将问题改为“第一个类”和“最后一个类”,下面介绍如何使用XPath进行编辑。这假设您的标记是有效的XHTML。如果没有,请切换回
加载HTML
(请参阅上面的代码):


如果您必须使用regex进行此操作(不建议这样做)。 我想这应该行得通

$dom = new DOMDocument;
$dom->loadXML( $html );
$xpath = new DOMXPath( $dom );
$first = $xpath->query( '/ul/li[1]/@class' )->item( 0 );
$last = $xpath->query( '/ul/li[last()]/@class' )->item( 0 );
$last->value .= ' last';
$first->value .= ' first';
echo $dom->saveXML( $dom->documentElement );
$replacement1=“*?\s”;
$string1=“$1 class_last”;
$ul=preg_replace($ul,$replacement1,$string1);)
$replacement2=“\s”;
$string2=“$1第一级”;
$ul=preg_replace($ul,$replacement2,$string2);)

如果你真的想用regex做这项工作,你可以试试:

$replacement1 = "<li\s.*?class="(.*?)".*?>.*?</li>\s</ul>";
$string1 = "$1 class_last";
$ul = preg_replace($ul, $replacement1, $string1);)

$replacement2 = "<ul.*?>\s<li\s.*?class="(.*?)".*?>";
$string2 = "$1 class_first";
$ul = preg_replace($ul, $replacement2, $string2);)
$ul=
'; //将输入字符串分解为数组 $lines=爆炸(“\n”,$ul); $found_first=0;//李先生是第一个被创立的人吗 $found_last=0;//最后一个李的索引 $class\u first=“class\u first”//第一节课 $class\u last=“class\u last”//最后一节课 //在所有线路上循环 对于($i=0;$i<计数($line);$i++){ $line=$line[$i]; //该行以开头。您可以使用计数器:

<ul id="menu">
<li id="some_id" class="some_class class_first">...</li>
<li id="some_id" class="some_class">...</li>
<li id="some_id" class="some_class class_last">...</li>
</ul>

此列表来自何处?@Happy:让我澄清@fabrik的问题:此字符串来自何处?我们已经知道
$ul
,因为它在您的问题中提供。(相关)@Happy:让我澄清一下我对@fabrik问题的澄清:是你生成了那个标记,还是你从某个第三方脚本收到了这个字符串?你可能的重复应该提到,这是CSS3,在旧浏览器中不兼容/被忽略。我会通过JavaScript来做这类事情。这是我考虑的+1+1选项!很好!这是我能想到的最干净的方式(服务器端)。谢谢,但是你是从哪里得到html/body的?在$ul里面只有
代码。@就像答案中说的那样:如果你使用
loadHTML
加载标记,DOM将切换到它的html解析器模块,该模块将添加html框架,例如doctype、html、body元素。如果你的html不是有效的XHTML,你需要
loadHTML
。如果你有有效的标记,你可以使用
loadXML
来代替。这个例子不起作用。在saveXML上,它给出的代码是head/>@Happy No,它不起作用。它给出了ULAlso的outerHTML,请参见我投票的问题:[需要一个正则表达式将css类添加到第一个和最后一个列表项]()如果他能在输出前更改CSS3,我不会使用CSS3。另外,他的
$ul
已经构建了列表元素,他需要,因此他不能像你提到的那样循环。他只有一个字符串。
$replacement1 = "<li\s.*?class="(.*?)".*?>.*?</li>\s</ul>";
$string1 = "$1 class_last";
$ul = preg_replace($ul, $replacement1, $string1);)

$replacement2 = "<ul.*?>\s<li\s.*?class="(.*?)".*?>";
$string2 = "$1 class_first";
$ul = preg_replace($ul, $replacement2, $string2);)
$ul = '
<ul id="menu">
<li id="some_id" class="some_class">...</li>
<li id="some_id" class="some_class">...</li>
<li id="some_id" class="some_class">...</li>
</ul>
';

// explode input string to an array
$lines = explode("\n", $ul);

$found_first = 0;   // is the first li founded
$found_last  = 0;   // index of the last li
$class_first = "class_first"; // class for the first li
$class_last  = "class_last";  // class for the last li

// loop on all lines
for ($i = 0; $i < count($lines); $i++) {
  $line = $lines[$i];

  // the line begins with <li
  if (preg_match("/^<li/", $line)) {

    // is it the first one
    if (!$found_first) {
      // add the class
      $lines[$i] = preg_replace('/ class="([^"]+?)"/', " class=\"$1 $class_first\"", $lines[$i]);
      // the first li have been found
      $found_first = 1;
    }
    // memo the last line proceded
    $found_last = $i;
  }
}

// this will add class_last even if the last li
// is also the first one (ie: only one li)
if ($found_last) {
  $lines[$found_last] = preg_replace('/ class="([^"]+?)"/', " class=\"$1 $class_last\"", $lines[$found_last]);
}

$ul = implode("\n", $lines);

echo $ul;
<ul id="menu">
<li id="some_id" class="some_class class_first">...</li>
<li id="some_id" class="some_class">...</li>
<li id="some_id" class="some_class class_last">...</li>
</ul>
<?php
$list = array('aaa', 'bbb', 'ccc', 'ddd');
$items = count($list); // count items in list
$i = 1; // set counter to one, because first item in list will be item number: 1

echo '<ul>';

// create loop
foreach($list as $value) {

  // first item
  if($i == 1) {
    $class = 'some_class first_class';

  // last item
  } elseif ($i == $items) {
    $class = 'some_class last_class';

  // not first / not last item
  } else {
    $class = 'some_class';
  }

  echo '<li id="some_id" class="'.  $class .'">' . $value . '</li>';
  $i++; // raise $i by one
}

echo '</ul>';
?>
<ul>
<li id="some_id" class="some_class first_class">aaa</li>
<li id="some_id" class="some_class">bbb</li>
<li id="some_id" class="some_class">ccc</li>
<li id="some_id" class="some_class last_class">ddd</li>
</ul>
<ul id="menu">
  <li>aaa</li>
  <li>bbb</li>
  <li>ccc</li>
  <li>ddd</li>
</ul>
#menu {
}

#menu li:first-child {
}

#menu li {
}

#menu li:last-child {
}