让我先谈谈:我猜我对正则表达式不好。真。在过去的4天里,我试图找出如何替换以下格式:
# Item number 1
# Item number 2
# Item number 3
依此类推,用:
<ol>
<li>Item number 1</li>
<li>Item number 2</li>
<li>Item number 3</li>
</ol>
等等。最初我想用/^\s\d\.\s/mi
替换<li>
,但我放弃的速度非常快,因为它更复杂。
所以我尝试使用preg_match_all
运行一个循环来获取所有可能的组,并将它们替换为html标记。但我做错了什么,我不知道是什么。任何帮助将非常感激。
这是我的代码($_POST
使用XHR处理的请求):
$innerhtml = htmlspecialchars(addslashes($_POST['innerhtml']));
$br_nums = '<br>';
if (strstr($innerhtml, PHP_EOL)) {
$innerhtml = preg_replace("/\r\n\r\n/", $br_nums, $innerhtml);
}
preg_match_all('/^\s[\#\.]\s.*/mi', $innerhtml, $outmatch);
if (isset($outmatch[0])) {
$origin_outmatc = $outmatch[0];
$outmatch = implode('[\r\n]', $outmatch[0]);
$original_match = $outmatch;
$outmatch = explode('<br>', $outmatch);
foreach ($outmatch as $key => $match) {
if (preg_match('/^\<br\>/i', $match) || preg_match('/^\<br\>\[\\r\\n\]/i', $match)) {
$match = str_replace('<br>', '', preg_replace('/^\[\\r\\n\]/i', '', $match));
}
}
$full_ol = '';
foreach($outmatch as $ol) {
$full_ol .= '<ol>';
$ol = preg_replace('/^\s[\#\.]\s/', '<li>', str_replace('[\r\n]', '</li>', $ol));
$full_ol .= $ol;
$full_ol .= '</ol>';
}
$full_ol = str_replace(' # ', '<li>', preg_replace('/(?:$|)\<(?!\/li\>)\/ol\>/i', '</li></ol>', $full_ol));
$full_ol = preg_replace('/(?:|^)\<ol\>[\r\n]\<\/li\>/i', '<ol>', $full_ol);
$full_ol = explode('<ol>', $full_ol);
foreach ($full_ol as $key => $list) {
if (empty($list)) {
unset($full_ol[$key]);
$full_ol = array_values($full_ol);
}
}
foreach ($full_ol as $key => $list) {
$full_ol[$key] = '<ol>' . $list;
}
$original_match = str_replace('<br>', '+SPLIT_HERE+<br>', str_replace('[\r\n]', "\r\n", $original_match));
$original_match = explode('+SPLIT_HERE+', $original_match);
foreach ($original_match as $key => $possible_match) {
if (!preg_match('/^\s\#\s/mi', $possible_match)) {
unset($original_match[$key]);
$original_match = array_values($original_match);
}
}
foreach ($full_ol as $key => $possible_match) {
if (preg_match('/^\<ol\>\<\/li\>\<\/ol\>$/i', $possible_match)) {
unset($full_ol[$key]);
$full_ol = array_values($full_ol);
}
}
// Preview
var_dump($original_match, $full_ol);
// Replace original with html version
$innerhtml = str_replace($original_match, $full_ol, $innerhtml);
}
请指导我 - 我怎样才能做得更好(或者至少做得对)?我很沮丧......谢谢。
答案 0 :(得分:0)
此代码应该有效。用phptester.net测试。
如果您有任何疑问,请记录下来:)<?php
$innerhtml = "
Hallo 123,
this is a little test
# jeah
# huhu
# third
line beetween?
# okay lets do this again
# second
# final
what about u?
";
$br_nums = '<br>';
// with that code it is not working. because double line breaks means normaly <p>
// if (strstr($innerhtml, PHP_EOL)) {
// $innerhtml = preg_replace("/\r\n\r\n/", $br_nums, $innerhtml);
// }
preg_match_all('/\s*#{1}\s*(.*)\n/', $innerhtml . "\n", $matches); // for last line matching
$olStarted = false;
if (!empty($matches[1])) {
foreach($matches[1] as $x => $match) {
$replace = '';
// start the ol, if is not started already
if (!$olStarted) {
$replace .= '<ol>';
$olStarted = true;
}
// build li
$replace .= '<li>' . $match . '</li>';
// end ol when of them is true
//
// 1* no next list item is there
// 2* next list item is there, but a line breaks are between them
if(
!isset($matches[0][$x + 1]) || // 1*
strpos($matches[0][$x + 1], "\n") === 1 // 2*
) {
$replace .= '</ol>';
$olStarted = false;
}
// actually replace the line
$innerhtml = str_replace($matches[0][$x], $replace, $innerhtml);
}
}
var_dump($innerhtml);
答案 1 :(得分:-1)
匹配# Item number 1
的正则表达式为:
\s*[#]\s+[iI][tT][eE][mM]\s+[nN][uU][mM][bB][eE][rR]\s+\[0-9]+\s*
这意味着:
(0+ spaces)#(1+ spaces)Item(1+ spaces)number(1+ spaces)123(0+ spaces)
例如:" # Item number 12 "
如果文本与此模式匹配,则只匹配下一个模式:
[iI][tT][eE][mM]\s+[nN][uU][mM][bB][eE][rR]\s+\[0-9]+\s*
通过匹配,您可以获得匹配字符串的索引开头。字符串从Match.Index
到Length
的子字符串,您将拥有此值:
Item number 1
Pd积
如果"Item"
可以变为任何字符串,只需写"\w+"
而不是"[iI][tT][eE][mM]"
。这同样适用于"number"
。
第二种方式:
匹配主模式:
\s*[#]\s+[iI][tT][eE][mM]\s+[nN][uU][mM][bB][eE][rR]\s+\[0-9]+\s*
找到匹配后,匹配下一个模式:
\s*[#]\s+
现在从"# item number 2"
到Match.Value.Length
的字符串Length - Match.Value.Length
子串。在这种情况下,子串从2到"# item number 2"
长度 - Match.Value.Length
。