当前位置: 首页 > 知识库问答 >
问题:

使用preg\u replace将字符串转换为标记

蔺弘
2023-03-14

这些正则表达式快把我累死了,不管我读什么,我都无法理解这个概念。

这是我的问题,我相信它非常容易解决。

[img:http://example.com/_data/025_img.jpg]

我只想用

<img src='http://example.com/_data/025_img.jpg' border='0' />

我尝试了各种愚蠢的变化,但都不起作用。我对此并不感到惊讶。

编辑

其他信息:

我的情况如下。

>

  • 用户上传图像到他们的配置文件

    图像名称存储在db中。

    我正在使用Codeigniter并将textarea通过视图传递到控制器中-

    然后我想扫描文本,看看用户在哪里有[img:...]标签,并将其交换成

    因此,用户的实际输入将与

    The brown fox jumped over foo bar [img:http://example.com/_data/025_img.jpg] and then went to bed [img:http://example.com/_data/0277_img.jpg] while thinking about [img:http://example.com/_data/1115_img.jpg]
    

    这就是我要求preg_replace而不是preg_match的原因。preg_match不会让文本跟随图像。


  • 共有3个答案

    东方震博
    2023-03-14

    正则表达式很难,但却很强大。我根本不是大师,所以不要认为这是最好的解决方案。

    $regEx = '/\[img:http:\/\/[\w]{3,10}\.(com|org|us){1}[\w\/]{5,15}\.(jpg|png|gif){1}\]/i';
    
    $string = 'someting before [img:http://example.com/_data/025_img.png], something after [img:http://example.org/_data/025_img.jpg] and end of the line EOL';
    $pstring = $string;
    $matches[0] = array();
    preg_match_all($regEx, $string, $matches);
    

    匹配数组看起来像:

    Array
    (
        [0] => Array
            (
                [0] => [img:http://example.com/_data/025_img.png]
                [1] => [img:http://example.org/_data/025_img.jpg]
            )
    
        [1] => Array
            (
                [0] => com
                [1] => org
            )
    
        [2] => Array
            (
                [0] => png
                [1] => jpg
            )
    
    )
    

    好吧,这是怎么回事:

    1. 正则表达式

    /-开始regexpression
    \[img:http:\/\/-每个字符串必须以[img:http://
    [\w]{3,10}-比我预期的只有3到10个数字、字母和下划线行,这是一个域名(尽管我不确定域必须包含下划线,所以优化的好点)
    \.-dot
    (com | org | us){1}-这些家伙中的一个
    [\w\/]{5,15}-从五行到十五行作为路径,注意我包括了/这里另外
    .-dot
    (jpg | png | gif){1}-这些家伙中的一个
    ]-模式结束
    /i-使其不区分大小写

    >

  • preg_match_all查找给定字符串中的所有匹配项,从分支到括号中的附加子字符串匹配项作为$matches的第二和第三个元素,我不知道为什么,因此如果有人能帮助理解这一点,我将不胜感激。

    接下来使用简单的字符串操作,我可以替换所有主菜

    类似这样的情况:(注意:没有if语句,因为我在开始时添加了空$matches[0],没有ifs:)生活会更好。)

    foreach ($matches[0] as $match) {
        $img = str_replace(array('[img:',']'), array('<img src="', '" />'), $match);
        $pstring = str_replace($match, $img, $pstring);
    }
    

    您可以随意使用正则表达式,根据需要使其变得简单或更复杂。

    $pstring输出为

    someting before <img src="http://example.com/_data/025_img.png" />, something after <img src="http://example.org/_data/025_img.jpg" /> and end of the line EOL
    

    这里是操场http://phpfiddle.org/main/code/bbu-e24

  • 席俊达
    2023-03-14

    如果你不喜欢正则表达式,你就不必使用它们。至少不是为了这个目的。

    应采取以下措施:

    $in = "[img:http://example.com/_data/025_img.jpg]";
    
    if (strpos($in, "[img:") === 0)
    {
        $in = "<img src='" . substr($in, 5, -1) . "' border='0' />";
    }
    
    echo $in;
    

    然而,这将是正则表达式的方式:

    $in = "[img:http://example.com/_data/025_img.jpg]";
    
    preg_match("~\[img\:(.*?)\]~", $in, $matches);
    
    if ($matches)
    {
        echo "<img src='" . $matches[1] . "' border='0' />";
    }
    

    简短解释:

    模式是:“~\[img\:(.*?\]~”

    我使用~作为模式的分隔符。你的起始[必须转义,因为它是一个regex字符。img可以保持原样,必须再次转义。之后,任何字符都可以跟在后面:*-问号是将选择变成“ungreedy”,否则,它将匹配到结尾。把它放进(大括号)因此,它被标记为$matches的输出。之后,再次关闭]即可。

    更新:参见Gumbos注释,不需要转义。

    孙修德
    2023-03-14

    让我们先把简单的事情弄清楚。

    /\[img:([^\]]+)\]/
    

    即:

    • 文字[img:

    通过preg_match运行此操作,匹配数组中的元素1很可能是一个图像URL,您可以轻松地将其插入到img标记中。

    但你不应该。不是马上。

    首先,这很不安全。当我写这篇文章时会发生什么?

    [img:javascript:alert(document.cookie);]
    

    哦。那可不好。

    您可能需要确保用户声称是URL的东西确实是URL。您可以通过调用parse_url来尝试这样做。它将返回一个URL组件数组。确保该对象具有域和路径,并且通过HTTP或HTTPS提供服务。

    好的,但是当用户输入这个时会发生什么?

    [img:http://www.example.com/foo.jpg" onmouseover="alert(document.cookie)"]
    

    那是有效的...算是...将被parse_url成功解构的URL,并且很可能通过格式良好的基本检查。过滤掉空格和引号(单引号和双引号)将是一个很好的起点,但仍有更多的事情需要担心。

    底线是,像这样的标记是XSS中的向量,或者是跨站点脚本漏洞。

    通过htmlspecialchars传递URL,您可能会减轻一些威胁。这至少会导致引用和括号中出现核武器,而且很难让那些被照顾的人感到不快。请注意字符集的愚蠢,一些非UTF-8字符编码可能包含ASCII引号。。。

    您可能希望为此使用真正的标记语言(即使只是标记),并且可能希望在结果上使用基于白名单的HTML过滤器,如HTML净化器。这将有助于保护你免受某种程度的精神错乱。

    记住,只有当他们没有抓住你的时候,你才是偏执狂。网络上到处都是愚蠢到恶意的人,也有恶意到愚蠢的人。

     类似资料:
    • 我只是无法在c中转换不同的数据类型,我知道c是一种强类型语言,所以我在这里使用了,但我面临一个问题,错误消息是 从“std::string{aka std::basic_string}类型转换为“int”类型的static_

    • 问题内容: 问题:转弯 进入 Perl支持可以在替换字符串中使用的“ \ L”操作。 模式类不支持此操作: 此类不支持的Perl构造:[…]预处理操作\ l \ u,\ L和\ U。 https://docs.oracle.com/javase/10/docs/api/java/util/regex/Pattern.html 问题答案: 您无法在Java正则表达式中执行此操作。您必须使用和手动进行

    • 问题内容: 如何将经典字符串转换为f字符串? 输出: 所需的输出: 问题答案: f字符串是 语法 ,而不是对象类型。您不能将任意字符串转换为该语法,该语法会创建一个字符串对象,而不是相反。 我假设您想用作模板,因此只需在对象上使用方法: 如果要提供可配置的模板服务,请创建一个包含所有可以插值的字段的名称空间字典,并与调用语法一起使用以应用名称空间: 然后,用户可以在字段中的名称空间中使用任何键(或

    • 问题内容: 该应用程序基本上通过输入初始速度和最终速度以及时间来计算加速度,然后使用公式来计算加速度。但是,由于文本框中的值是字符串,所以我无法将它们转换为整数。 问题答案: 基本概念, 请注意,这仅在Swift 1.x中有效 Swift 4更新

    • 问题内容: Oracle Java Community网站上的一篇文章提供了以下方法作为示例(对于JPA Converter,但这并不相关): 将String y强制转换为String val有什么用?有正当的理由吗? 原始文章:JPA的新增功能 问题答案: 这样的转换是完全没有必要的。我可以想象那是以前 但是后来参数类型更改为,而作者只是忘了删除强制类型转换。

    • 问题内容: 是否可以将模板字符串创建为常规字符串 然后将其转换为模板字符串 没有,以及其他动态代码生成方式? 问题答案: 由于您的模板字符串必须动态地(在运行时)引用该变量,因此答案是: 否,没有动态代码生成是不可能的。 但这很简单: