V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
CNCCTV
V2EX  ›  PHP

请问这个替换内容怎么写正则表达式?

  •  
  •   CNCCTV · 2015-08-06 08:17:41 +08:00 · 2972 次点击
    这是一个创建于 3401 天前的主题,其中的信息可能已经有所发展或是发生改变。
    一个php配置文件的内容
    <?php
    $title='nihao';
    $content1='<b style="color:red;">欢迎!</b>
    <a href="reg.php" class="btn">注册</a>
    <a href="login.php" class="btn">登录</a>';
    $content2='站点暂时关闭
    开放时间未知';
    ?>
    content1和content2里的内容都是换行的。
    第一个变我量能替换内容,但是第二个变量就出问题了。请问怎么写正这个则表达式啊?
    25 条回复    2015-08-06 18:35:43 +08:00
    loveyu
        1
    loveyu  
       2015-08-06 08:25:58 +08:00 via Android
    你要替换什么内容
    popok
        2
    popok  
       2015-08-06 08:33:13 +08:00
    问题描述清楚些
    realpg
        3
    realpg  
       2015-08-06 08:33:31 +08:00
    whisperer
        4
    whisperer  
       2015-08-06 08:40:47 +08:00
    匹配换行符?
    sciooga
        5
    sciooga  
       2015-08-06 10:07:14 +08:00 via Android
    不要使用 小数点 表示任何字符,使用[\S\s] 表示任何字符,这样不会受跨行影响。
    neoFaster
        6
    neoFaster  
       2015-08-06 11:52:11 +08:00
    先把问题写清楚,语句通顺怎么先得做到吧。
    fox0001
        7
    fox0001  
       2015-08-06 13:39:17 +08:00 via Android
    正则表达式加m和s结尾,m表示匹配多行,s表示.号匹配h换行符
    CNCCTV
        8
    CNCCTV  
    OP
       2015-08-06 15:04:21 +08:00
    @loveyu @popok @whisperer @sciooga @neoFaster @fox0001
    我是想把单引号中的内容替换,
    我用的方法是把变量作为匹配开始的字段。
    <?php
    //接收提交的变量名
    $name=$_POST['name'];
    //接收提交的内容
    $new_content=$_POST['new_content'];
    //判断是否有这个文件
    $file_path="config.php";
    if(file_exists($file_path)){
    if($fp=fopen($file_path,"a+")){
    //读取文件
    $conn=fread($fp,filesize($file_path));
    //替换字符串,把内容替换成$new_content的内容。
    $conn=preg_replace('/'.$name.'=\'?.+\';/im',
    $name.'=\''.$new_content.'\';',
    $conn);
    // 保存修改结果。
    file_put_contents($file_path, $conn);
    // 关闭资源
    fclose($fp);
    }
    }else{
    echo "没有这个文件";
    }
    ?>
    但是换行的内容替换不了。
    popok
        9
    popok  
       2015-08-06 15:18:26 +08:00
    . 匹配除换行符以外的任意字符

    所以换行符是匹配不到的,正如5楼说的,换[\s\S]或[\w\W]都行,比如?.+换成[\w\W]+
    popok
        10
    popok  
       2015-08-06 15:21:56 +08:00
    哦,上面那个title匹配过多了,应该是勉强模式重复,应该是这个[\w\W]*?
    popok
        11
    popok  
       2015-08-06 15:23:25 +08:00
    $conn=preg_replace('/'.$name.'=\'[\w\W]*?\';/im',
    $name.'=\''.$new_content.'\';',
    $conn);
    CNCCTV
        12
    CNCCTV  
    OP
       2015-08-06 15:24:07 +08:00
    @popok 不行啊,会把下一个变量和单引号中的内容也覆盖了。
    CNCCTV
        13
    CNCCTV  
    OP
       2015-08-06 15:27:34 +08:00
    @popok 11楼的方法是可以的
    ellipse42
        14
    ellipse42  
       2015-08-06 15:32:35 +08:00
    CNCCTV
        15
    CNCCTV  
    OP
       2015-08-06 15:35:25 +08:00
    @popok 还有一个问题,如果提交的内容有单引号,怎么去处理?难度又用正则替换吗?
    feiyuanqiu
        16
    feiyuanqiu  
       2015-08-06 15:37:55 +08:00
    我大概看懂了需求了,意思是想根据输入的属性名替换属性值?比如输入是 $name = 'href'; $new_content = 'test'
    就把 config.php 改为 $content1='<b style="color:red;">欢迎!</b>
    <a href="test" class="btn">注册</a>
    <a href="test" class="btn">登录</a>';

    如果是这样的话,把正则改一下就行了

    $reg = '/(' . $name . ')="([^"]*)"/sim';
    $conn = preg_replace($reg, '${1}="'.$new_content.'"', $content1);
    CNCCTV
        17
    CNCCTV  
    OP
       2015-08-06 15:52:08 +08:00
    @feiyuanqiu 是以变量名称作为匹配开始的字段,再以';作为结束,如$title='';,然后把单引号中的内容替换。
    CNCCTV
        18
    CNCCTV  
    OP
       2015-08-06 15:53:24 +08:00
    @feiyuanqiu 而有些内容会有换行的。
    feiyuanqiu
        19
    feiyuanqiu  
       2015-08-06 16:01:18 +08:00
    @CNCCTV 哦,懂了
    既然config.php是php文件,你为什么不 include 进来直接改变量值就行了嘛?

    $content = file_get_contents('config.php');

    $search = '\$content2';
    $replace = 'test';
    $reg = '/(' . $search . ')=\'([^\']*)\'/sim';
    $replaced = preg_replace($reg, '${1}=\''.$replace.'\'', $content);
    CNCCTV
        20
    CNCCTV  
    OP
       2015-08-06 16:08:16 +08:00
    @feiyuanqiu 是因为想做成后台修改配置,也可以做成安装配置用,而不是上FTP去修改文件。
    popok
        21
    popok  
       2015-08-06 16:20:55 +08:00
    不怕啊,因为正则是';结尾的,所以就会匹配到;分号结束,内容里不要同时';连着出现就没问题啊
    CNCCTV
        22
    CNCCTV  
    OP
       2015-08-06 16:38:10 +08:00
    @popok 为了防止提交的内容有单引号,我还是用正则来转义字符一下好了
    // 把' 换成 \'
    $new_content=preg_replace('/\'/',"\'",$new_content);
    loveyu
        23
    loveyu  
       2015-08-06 17:00:07 +08:00
    修改配置不是应该直接使用$cfg = var_export(['name'=>'test'], true);这样生成的数组直接替换原文件么,正则替换不怕出错?
    feiyuanqiu
        24
    feiyuanqiu  
       2015-08-06 17:05:20 +08:00
    @CNCCTV 我觉得你这个通过正则处理配置文件的思路不太好,要考虑很多输入情况,正则写起来很麻烦而且不容易写正确。

    把配置文件弄成一个配置数组,要读取直接 include,要写入直接 var_export,简单又可靠

    function setConfig($name, $value)
    {
    $configPath = __DIR__ . DIRECTORY_SEPARATOR . 'config.php';

    static $config;
    if (is_null($config)) {
    $config = include $configPath;
    }

    register_shutdown_function(function () use (&$config, $configPath) {
    if ($fp = fopen($configPath, 'w+')) {
    $content = sprintf('<?php return %s;', var_export($config, true));
    fwrite($fp, $content, strlen($content));
    }
    });

    $config[$name] = $value;
    }
    fox0001
        25
    fox0001  
       2015-08-06 18:35:43 +08:00 via Android
    $conn=preg_replace('/'.$name.'=\'.+?\';/ims',
    $name.'=\''.$new_content.'\';',
    $conn);
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   3481 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 40ms · UTC 11:02 · PVG 19:02 · LAX 03:02 · JFK 06:02
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.