PHP或Regex用于唯一匹配ID

时间:2015-02-06 01:29:09

标签: php html regex

这里有一些存储在数据库表中的东西:

<section id="earth">
  <h2>Earth</h2>
  <div class="MainDiv">
    (article)
  </div>
</section>

<section id="mars">
  <h2>Mars</h2>
  <div class="MainDiv">
    (article)
  </div>
</section>

我想要做的就是修改显示,这样每个部分都有一个唯一的数据目标,每个div都有一个匹配的ID。 (我给了div一个类 - MainDiv - 将它们与它们可能包含的任何嵌套div区分开。)

<section id="earth" data-target="a">
  <h2>Earth</h2>
  <div class="MainDiv" id="a">

<section id="mars" data-target="b">
  <h2>Mars</h2>
  <div class="MainDiv" id="b">

理想情况下,我希望保留数据目标并匹配ID的简单 - 单个小写字母将是完美的。是否有PHP功能可以做到这一点?如果没有,你知道一个可行的正则表达式脚本吗?

2 个答案:

答案 0 :(得分:1)

不,尽可能不在正则表达式上完成此任务。这就是HTML解析器的用途。已经有一个PHP类,它的DOMDocument

首先,只需加载类(这是内置的),然后加载HTML标记,获取所需的所有元素(在本例中为section标签)。获得所有节标记后,迭代找到的标记并为每个标记添加所需的数据属性(包括div标记),然后再将它作为字符串重新组合在一起。这里有一些可以帮助你入门。粗略的例子:

$i = 1; // initialize counter
// initialize DOMDocument
$dom = new DOMDocument;
@$dom->loadHTML($html); // load the markup

$sections = $dom->getElementsByTagName('section'); // get all section tags
if($sections->length > 0) { // if there are indeed section tags inside
    // work on each section
    foreach($sections as $section) { // for each section tag

        $section->setAttribute('data-target', 'section' . $i); // set id for section tag

        // get div inside each section
        foreach($section->getElementsByTagName('div') as $div) {
            if($div->getAttribute('class') == 'MainDiv') { // if this div has class maindiv
                $div->setAttribute('id', 'div' . $i); // set id for div tag
            }
        }

        $i++; // increment counter
    }
}

// back to string again, get all contents inside body
$html = '';
foreach($dom->getElementsByTagName('body')->item(0)->childNodes as $child) {
    $html .= $dom->saveHTML($child); // convert to string and append to the container
}

// output
echo $html;

Sample Output

答案 1 :(得分:1)

我会建议 @Barmar 。做a0a1a2,...,这样我们可以通过循环在PHP中拥有尽可能多的echo <section>。如果我们来自abc,...,z下一步会是什么? aa?你必须对其进行编程。对于每个元素,我将使用一个简单的for循环并使用每个元素的索引。例如:

class Planet
{
    public $title;
    public $name;
    public $article;
    function __construct($title, $name, $article) {
        $this->name = $name;
        $this->title = $title;
        $this->article = $article;
    }
}

$planets = array(
    new Planet("earth", "Earth", "Hello World!"),
    new Planet("mars", "Mars", "Hello World Again!")
);

for( $i = 0; $i < count($planets); $i++ ) {
    $id = strtolower($planets[$i]->name);
    $name = $planets[$i]->name;
    $article = $planets[$i]->article;
    echo <<<HERE
<section id="$id" data-target="a$i">
  <h2>$name</h2>
  <div class="MainDiv" id="a$i">
    $article
  </div>
</section> 

HERE;
}

会给出输出:

<section id="earth" data-target="a0">
  <h2>Earth</h2>
  <div class="MainDiv" id="a0">
    Hello World!
  </div>
</section>  
<section id="mars" data-target="a1">
  <h2>Mars</h2>
  <div class="MainDiv" id="a1">
    Hello World Again!
  </div>
</section>