【问题标题】:PHP: how to replace text, but only between certain identifiers?PHP:如何替换文本,但仅限于某些标识符之间?
【发布时间】:2012-10-20 00:56:48
【问题描述】:

在 PHP 中,我需要帮助来替换某些标识符之间的文件中的某些内容。

例如:

abcde
-BEGIN-
   bcdef
-END-
cdefg
-BEGIN-
   doo wah diddy
-END-
defgh

假设我需要将“d”字符替换为“z”,但仅-BEGIN--END- 部分之间。结果将是:

abcde
-BEGIN-
   bczef
-END-
cdefg
-BEGIN-
   zoo wah zizzy
-END-
defgh

我尝试preg_match_all 成功识别 -BEGIN- 到 -END- 部分:

$text = file_get_contents($file);
preg_match_all('#-BEGIN-.*?-END-#s', $text, $matches);

但无法弄清楚如何替换这些匹配项中的某些内容并返回包括正确替换在内的整个文本。

有什么想法吗?

【问题讨论】:

  • 你试过preg_replace('/a([^(\-BEGIN\-|\-END\-)])/', 'z$1',$text)吗?

标签: php regex preg-match-all


【解决方案1】:

Preg_replace() 应该可以解决问题。

【讨论】:

  • 那怎么办?我需要一个正则表达式来识别该部分,然后仅在每个 -BEGIN- 和 -END- 之间替换 d
  • 使用preg_replace_callback 分离出块,然后在所述回调中使用第二个正则表达式或字符串函数来替换搜索到的字母。
【解决方案2】:

这会搜索 -BEGIN--END- 内的块,然后将所有出现的 d 字符替换为 z(因此第三行中的preg_replace() 函数)。

$str = preg_replace_callback(
    '~(?<=(?<=\n|^)-BEGIN-\n).*?(?=\n-END-)~s',
    create_function('$m','return preg_replace("~d~s","z",$m[0]);'),
    $str
);

编辑 1: 将两个正则表达式规则中的 m 标志更改为 s


编辑 2: 如果您想确保这里有更好的正则表达式版本(考虑到所有可能的换行符 - Windows、Unix 等)。
    '~(?<=
        (?<=\n|\r|\r\n|^)   -BEGIN- \n |
        (?<=\n|\r|\r\n|^)   -BEGIN- \r |
        (?<=\n|\r|\r\n|^)   -BEGIN- \r\n
    )
    .*?
    (?=
        \n      -END-   (?=\n|\r|\r\n|$) |
        \r      -END-   (?=\n|\r|\r\n|$) |
        \r\n    -END-   (?=\n|\r|\r\n|$)
    )~xs',

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-05
    • 2014-08-15
    • 1970-01-01
    • 2015-11-19
    • 1970-01-01
    • 2020-07-29
    • 1970-01-01
    相关资源
    最近更新 更多