Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在多行重复模式上应用PHP正则表达式替换_Php_Regex - Fatal编程技术网

在多行重复模式上应用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";
    }