【问题标题】:php preg_replace remove entire line (from a block of many lines ) if it contains an occurence of a wordphp preg_replace 如果包含出现的单词,则删除整行(从多行的块中)
【发布时间】:2013-07-02 05:24:00
【问题描述】:

伙计们(preg_replace 大师);

我正在寻找一个 preg_replace sn-p ,我可以在 php 文件中使用它,如果某个单词出现在特定行中,则该整行将被删除/替换为空行

伪代码:

$unwanted_lines=array("word1","word2"."word3");
$new_block_of_lines=preg_replace($unwanted_lines, block_of_lines);

谢谢。

【问题讨论】:

    标签: php regex preg-replace


    【解决方案1】:

    表达式

    首先,让我们计算出匹配单词数组所需的表达式:

    /(?:word1|word2|word3)/
    

    (?: ... ) 表达式创建一个组,但不将其内容捕获到内存位置。单词由管道符号分隔,以便匹配任一单词。

    要使用 PHP 生成此表达式,您需要以下构造:

    $unwanted_words = array("word1", "word2", "word3");
    $unwanted_words_match = '(?:' . join('|', array_map(function($word) {
        return preg_quote($word, '/');
    }, $unwanted_words)) . ')';
    

    您需要preg_quote() 从常规字符串生成有效的正则表达式,除非您确定它是有效的,例如"abc" 不需要引用。

    另见:array_map()preg_quote()

    使用线数组

    您可以将文本块拆分为行数组:

    $lines = preg_split('/\r?\n/', $block_of_lines);
    

    然后,您可以使用preg_grep() 过滤掉不匹配的行并生成另一个数组:

    $wanted_lines = preg_grep("/$unwanted_words_match/", $lines, PREG_GREP_INVERT);
    

    另见:preg_split()preg_grep()

    使用单个preg_replace()

    要匹配包含多行文本块中不需要的单词的整行,您需要使用行锚,如下所示:

    /^.*(?:word1|word2|word3).*$/m
    

    使用 /m 修饰符,锚点 ^$ 分别匹配行的开头和结尾。两边的.*“刷新”匹配词左右的表达式。

    需要注意的一点是$ 匹配就在实际行结束字符(\r\n\n)之前。如果您使用上面的表达式执行替换,它将不会替换行尾本身。

    您需要通过像这样扩展表达式来匹配这些额外的字符:

    /^.*(?:word1|word2|word3).*$(?:\r\n|\n)?/m
    

    我在$ 锚点后面添加了(?:\r\n|\n)? 以匹配可选的行尾。这是执行替换的最终代码:

    $replace_match = '/^.*' . $unwanted_words_match . '.*$(?:\r\n|\n)?/m';
    $result = preg_replace($replace_match, '', $block_of_lines);
    

    Demo

    【讨论】:

    • @HamZa \n 始终存在,有时前面有 \r :) 可能存在性能方面的考虑。
    • @Jack - 无法使用您的代码,因为我无法理解 $words_re 的部分正则表达式的含义
    • 以及删除整行的部分需要额外的技巧......部分。
    • @MarcoZen 如果你是这个意思,我可以详细说明我的答案:) 给我一点时间。
    • @Jack - 那太好了。谢谢。还有一种方法我可以使用 DevZero 一个衬垫 $newstring = preg_replace("/^.*word1.*$/", "", $string) 进入某种 for 循环,并使其在通过时删除行一个数组?
    【解决方案2】:

    这个正则表达式可以从一行中删除匹配项

    $newstring = preg_replace("/^.*word1.*$/", "", $string);
    

    【讨论】:

    • @DevZero,如果单词出现,这会删除整行还是只删除该行中的单词?
    • 这会删除整行
    【解决方案3】:

    正如@jack 所指出的,我们只使用preg_quote() && array_map()

    $array = array('word1', 'word2', 'word3', 'word#4', 'word|4');
    $text = 'This is some random data1
    This is some word1 random data2
    This is some word2 random data3
    This is some random data4
    This is some word#4 random data5
    This is some word|4 random data6
    This is some word3 random data7'; // Some data
    
    $array = array_map(function($v){
        return preg_quote($v, '#');
    }, $array); // Escape it
    $regex = '#^.*('. implode('|', $array) .').*$#m'; // construct our regex
    $output = preg_replace($regex, '', $text); // remove lines
    echo $output; // output
    

    Online demo

    【讨论】:

    • 对于包含# 的单词失败,例如"word#4"
    • 现在,当你有"word|4" =D
    • Hamza - Jack - 伙计们? :)
    • 你现在应该已经意识到使用preg_quote()是唯一的出路:)
    • 你无法逃脱命运 ;-)
    猜你喜欢
    • 2022-11-30
    • 1970-01-01
    • 2020-09-09
    • 2014-04-20
    • 1970-01-01
    • 2013-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多