我正在使用此代码来检测内容的时间戳。
$pattern = '/(?<!:)\d{1,2}:\d{2}(?::\d{2})?(?!(?::\d{2})?\s*[ap]\.?m\.?)(?!.*?["\'])/';
$replacement = '[spp-timestamp time="$0"]';
$foundTimestamp = preg_replace ($pattern,$replacement, $content);
检测短代码的时间戳[spp-timestamp time =“00:00”]
只是想在此添加更多逻辑,以便不从所选div中选择时间戳,例如
<div class="sm2-inline-duration timestamp">0:00</div> and
<div class="sm2-inline-time timestamp">0:00</div>
例如,如果我将类“timestamp”放在任何div中,则不应使用正则表达式选择它。
有可能吗?
现在它正在检测邮票
00:00,00:00:00,0:00,0:00:00,不选择Am或PM
答案 0 :(得分:1)
您需要使用DOMDocument
解析带有XPath
的HTML,这样您就可以使用更简单的正则表达式进行替换。 //div[not(contains(@class, "timestamp"))]
xpath表达式将阻止修改div
属性中包含timestamp
子字符串的class
元素的内容。
$html = <<<DATA
<body>
<div class="sm2-inline-duration timestamp">0:00</div>
<div class="sm2-inline-time timestamp">0:00</div>
<div class="sm2-inline-duration">0:00</div>
<div class="sm2-inline-duration">Do not touch this</div>
</body>
DATA;
$dom = new DOMDocument('1.0', 'UTF-8');
$dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
$pattern = '/(?<!:)\d{1,2}:\d{2}(?::\d{2})?(?!(?::\d{2})?\s*[ap]\.?m\.?)/i';
$replacement = '[spp-timestamp time="$0"]';
$xpath = new DOMXPath($dom);
$divs = $xpath->query('//div[not(contains(@class, "timestamp"))]');
foreach($divs as $div) {
$div->nodeValue = preg_replace ($pattern,$replacement, $div->nodeValue);
}
echo $dom->saveHTML();
请参阅PHP demo
出于教育目的,这是一种基于正则表达式的方法,因为这对于使用任意HTML 安全生产无效。
我们的想法是使用可选的捕获组替换无限宽度的不受支持的负向lookbehind,如果组匹配则检查preg_replace_callback
内部,并使用相应的替换(如果匹配,我们需要保留原始匹配文本,否则,替换我们的自定义替换)。
$pattern = '/(<div\s+[^<]*?\bclass="[^<"]*\btimestamp\b[^<]*?>[^<]*)?(?<!:)\d{1,2}:\d{2}(?::\d{2})?(?!(?::\d{2})?\s*[ap]\.?m\.?)(?!.*?["\'])/';
$replacement = '[spp-timestamp time="$0"]';
$foundTimestamp = preg_replace_callback($pattern,function($m) {
return empty($m[1]) ? '[spp-timestamp time="'. $m[0] . '"]' : $m[0];
}, $content);
echo $foundTimestamp;