PHP中的通配符替换

One*_*erd 2 php regex

我没有在PHP中使用正则表达式的经验,所以我通常使用一系列str_replace(),substr(),strpos(),strstr()等来编写一些复杂的函数(你明白了).

这次我想要正确地执行此操作,我知道我需要使用正则表达式,但我对使用什么(ereg或preg)以及语法应该是多么困惑.

注意:我不解析HTML或XML,有时我将使用除(例如,|或〜或[tag]或::)之外的分隔符.我正在寻找一种使用正则表达式在两个已知分隔符之间进行通配符替换的通用方法,我没有构建HTML或XML解析器.

我需要的是一个替代这个的正则表达式:

<sometag>everything in here</sometag>
Run Code Online (Sandbox Code Playgroud)

有了这个:

<sometag>new contents</sometag>
Run Code Online (Sandbox Code Playgroud)

我已经在线阅读了一些文档,但我很困惑,希望你们中的一个正则表达式专家能够提供一个简单的解决方案.我怀疑我会将值传递给函数,如下所示:

$new_text = swapText ( "<sometag>", $the_new_text_to_go_into_the_dag );

function swapText ( $in_tag_with_brackets_to_update, $in_new_text ) {
 // define tags
 $starting_tag  = $in_tag_with_brackets_to_update;
 $ending_tag    = str_replace( "<", "</", $in_tag_with_brackets_to_update) );

 // not sure if this is the proper regex match string or not
 // and/or if any escaping needs to be done on the tags
 $find_string         = "{$starting_tag}.*{$ending_tag}";
 $replace_with_string = "{$starting_tag}{$in_new_text}{$ending_tag}";

 // after some regex, this function should return new version of <tag>data</tag>
}
Run Code Online (Sandbox Code Playgroud)

谢谢.

tro*_*skn 10

你说你不打算解析xml,然后继续展示一个xml示例.这有点令人困惑.

现在,你不能使用正则表达式来解析xml的原因是它们不是上下文的.因此,存在一类不能用于正则表达式的问题.这包括嵌套标签(无论它们是否为xml),因此请记住这一点.

那个,你应该使用preg- 不是ereg.ereg是一种较少使用,较慢且现已弃用的正则表达式.忘掉它.

在PCRE(Perl兼容正则表达式),这是浸渍料的用途,一个语言.(点)是一个通配符,匹配任何单个字符(除换行符).你可以在比赛后放一个量词.量词可以是明确的数字范围,例如{1,3}(意思是至少一个,但最多3个),或者您可以使用其中一个简写符号,例如+(简称{1,},意思是至少一个)或*(含义任意数字) ,包括零).有了这些知识,你可以匹配任何东西.*.

默认情况下,表达式将匹配最大可能的模式(称为贪婪).您可以使用?修改器更改此设置.因此.*?将匹配任何东西,但采取最短的模式.然后可以使用它来匹配任何分隔值,如下所示:

~<foo>.*?</foo>~
Run Code Online (Sandbox Code Playgroud)

请注意,我在~这里使用作为分隔符,以避免/在表达式中转义.标准是/用作分隔符,在这种情况下表达式看起来像这样:

/<foo>.*?<\/foo>/
Run Code Online (Sandbox Code Playgroud)

一般来说,上面是不好的做法,因为匹配一个否定的字符类比一个点更好,但为了让你的事情变得简单,只要忽略这一点,直到你得到你皮肤下的基础知识.它在大多数情况下都有效.特别是,由于.与换行符不匹配,如果内容包含换行符,则不起作用.如果需要,可以执行以下两种操作之一:向表达式添加修饰符,或者.用包含换行符的字符类替换.例如[\s\S](含义一个空白字符一个非空白字符,这是相同的东西).这就是表达式的外观:

~<foo>.*?</foo>~s
Run Code Online (Sandbox Code Playgroud)

要么:

~<foo>[\s\S]*?</foo>~
Run Code Online (Sandbox Code Playgroud)

为了使所有这些工作,让我们将它传递给preg_replace函数:

echo preg_replace('~<foo>.*?</foo>~s', '<foo>Lorem Ipsum</foo>', $input);
Run Code Online (Sandbox Code Playgroud)

如果您的标记名称是可变的,则可以像使用SQL查询一样构建表达式.就像SQL一样,你需要转义某些字符.使用preg_quote为:

function swapText($tagname, $replacement_text, $input) {
  $tagname_escaped = preg_quote($tagname, '~');
  return preg_replace(
    '~<' . $tagname_escaped . '>.*?</' . $tagname_escaped . '>~s',
    '<' . $tagname . '>' . $replacement_text . '</' . $tagname . '>',
    $input);
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`.`匹配除*换行符之外的任何*.除此之外,优秀的答案! (2认同)