在多行重复模式上应用PHP正则表达式替换
假设我有这个输入:在多行重复模式上应用PHP正则表达式替换,php,regex,Php,Regex,假设我有这个输入: I can haz a listz0rs! # 42 # 126 I can haz another list plox? # Hello, world! # Welcome! 我想将其拆分,使每组哈希起始行成为一个列表: I can haz a listz0rs! <ul> <li>42</li> <li>126</li> </ul> I can haz another list pl
I can haz a listz0rs!
# 42
# 126
I can haz another list plox?
# Hello, world!
# Welcome!
我想将其拆分,使每组哈希起始行成为一个列表:
I can haz a listz0rs!
<ul>
<li>42</li>
<li>126</li>
</ul>
I can haz another list plox?
<ul>
<li>Hello, world!</li>
<li>Welcome!</li>
</ul>
这是很好的,但是它没有区分两个不同的列表。我需要一种方法,使量词返回所有引用的串联字符串,或者,理想情况下,返回所有引用的数组
理想情况下,这应该是我的输出:
Array
(
[0] => Array
(
[0] => 42
[1] => 126
)
[1] => Array
(
[0] => Hello, world!
[1] => Welcome!
)
)
有没有办法做到这一点,如果没有,有没有一个接近的替代方案?我想说的是,不要试图在一个正则表达式中完成这一切-而是首先使用正则表达式来匹配所有以
.
符号开头的连续行集,并用
对来包装这些行。然后使用第二个正则表达式(或者根本不使用正则表达式-您可以在换行符上拆分)匹配每一行,并将其转换为格式。如果是我,我会:
将(“\n”,$input)分解为一个数组,其中1个键=行
foreach通过那个数组
每当你得到一行不是以#开头的,那就是你添加结束/开始ul标签的时候
再添加一点来处理意外输入(如一行中有两行非散列行),这样就很好了。您可以完全避免使用regex,只需尝试一种更简单的方法,让它逐行读取文件(一个行数组),每次遇到非散列起始行时,它都会启动一个新列表。像这样:
// You can get this by using file('filename') or
// just doing an explode("\n", $input)
$lines = array(
'I can haz a listz0rs!',
'# 42',
'# 126',
'I can haz another list plox?',
'# Hello, world!',
'# Welcome!'
);
$hashline = false;
$lists = array();
$curlist = array();
foreach ($lines as $line) {
if ($line[0] == '#')
$curlist[] = $line;
elseif ($hashline) {
$lists[] = $curlist;
$curlist = array();
$hashline = false;
}
}
可能需要进行一些清理,但希望能有所帮助
(阅读新答案后,这基本上是对语法错误答案的深入解释。)
编辑:您可能希望它也去掉每行开头的#。看起来已经解释了我在做什么。但是这里有一个链接,指向一个。对于这样的结构化内容,我不会以正则表达式的形式执行此操作。另一种方法怎么样
$your_text = <<<END
I can haz a listz0rs!
# 42
# 126
I can haz another list plox?
# Hello, world!
# Welcome!
END;
function printUnorderedList($temp) {
if (count($temp)>0) {
print "<ul>\n\t<li>" .implode("</li>\n\t<li>", $temp) . "</li>\n</ul>\n";
}
}
$lines = explode("\n", $your_text);
$temp = array();
foreach($lines as $line) {
if (substr($line, 0, 1) == '#') {
$temp[] = trim(substr($line,1));
} else {
printUnorderedList($temp);
$temp = array();
echo $line . "\n";
}
}
printUnorderedList($temp);
$your_text=如果要使用正则表达式执行此操作,需要两个。使用regex^(#.*\r?\n)+
匹配每个列表并在其周围添加标记。在每个列表中(由第一个正则表达式匹配),搜索^#.*
并将其替换为$0
,以在每个列表项周围添加标记。两个正则表达式都需要^
在换行符处匹配(/m
在PHP中为标志)
在PHP中,您可以使用preg_replace_callback
和preg_replace
在几行代码中实现这一点
$result = preg_replace_callback('/^(#.*\r?\n)+/m', 'replacelist', $subject);
function replacelist($groups) {
return "<ul>\n" .
preg_replace('/^#.*/m', ' <li>$0</li>', $groups[0])
. "</ul>\n";
}
$result=preg_replace_回调('/^(#.*\r?\n)+/m',replacelist',$subject);
函数替换列表($groups){
返回“\n”。
preg_replace('/^.*/m','- $0
',$groups[0])
.“
\n”;
}
我也想过这样做,但问题是你不能量化行,所以当你用ul标签包装它们时,你将包装每一行而不是整个集合。使用多行正则表达式,你可以一次匹配多行。您只需要在它们之间匹配空格换行符。
$result = preg_replace_callback('/^(#.*\r?\n)+/m', 'replacelist', $subject);
function replacelist($groups) {
return "<ul>\n" .
preg_replace('/^#.*/m', ' <li>$0</li>', $groups[0])
. "</ul>\n";
}