正则表达式替换特定标记内所有出现的单个字符

时间:2013-09-02 21:51:53

标签: php regex

我想知道是否可以使用一组正则表达式搜索/替换模式来替换2个标记中包含的字符串内所有特定字符的出现。

例如,是否可以用TOKEN1和&之间的文本空格替换所有句点。 TOKEN2如下例所示?

那样:

TOKEN1:Run.Spot.run:TOKEN2

更改为:

TOKEN1:Run Spot run:TOKEN2

注意:正则表达式需要能够替换任何文本中的任意数量的句点,而不仅仅是上面的特定模式。

我更多地问这个问题是因为我的个人知识,因为我过去曾想过多次使用各种正则表达式实现。然而,在这种特殊情况下,正则表达式将在php中。

我对php解决方法不感兴趣,因为我知道如何做到这一点。我正在努力扩展我对正则表达式的了解。

由于

3 个答案:

答案 0 :(得分:4)

一种方法:

$pattern = '~(?:TOKEN1:|\G(?<!^))(?:[^:.]+|:(?!TOKEN2))*\K\.~';
$replacement = ' ';
$subject = 'TOKEN1:Run.Spot.run:TOKEN2';
$result = preg_replace($pattern, $replacement, $subject);

模式细节:

~                  # pattern delimiter
(?:                # open a non capturing group
    TOKEN1:        # TOKEN1:
  |                # OR
    \G(?<!^)       # a contiguous match but not at the start of the string
)                  # close the non capturing group
(?:                # open a non capturing group
    [^:.]+         # all that is not the first character of :TOKEN2 or the searched character
  |                # OR
    :(?!TOKEN2)    # The first character of :TOKEN2 not followed by the other characters
)*                 # repeat the non capturing group zero or more times
\K                 # reset the match
\.                 # the searched character
~                  # delimiter

我们的想法是使用\G强制每个匹配为TOKEN1:或与先前匹配相匹配的匹配。

注意:默认行为类似于html标记(在关闭之前它始终处于打开状态)。如果找不到:TOKEN2\.后将替换所有TOKEN1:个字符。

答案 1 :(得分:0)

我认为最好的方法是写下这样的东西:

$result =
    preg_replace_callback(
        '/(TOKEN1:)([^:]+)(:TOKEN2)/g',
        function ($matches) {
            return $matches[0]
                   . preg_replace('/[.]/g', ' ', $matches[1])
                   . $matches[2];
        },
        'TOKEN1:Run.Spot.run:TOKEN2'
    );

(免责声明:未经测试。)

答案 2 :(得分:0)

最简单的是,您需要一个转义(\)句点(因为句点通常与任何字符匹配)作为您的模式:\.,并且您将用空格替换它:{{1 }}

这会将的所有实例替换为.

但是,根据您的评论,您似乎要求使用正则表达式替换字词之间的所有句点:

对于单词字符,您需要一个正(零宽度非捕获)lookbehind:(?<=\w)\.(?=\w) ,您的转义句点((?<=\w))和一个单词字符的正(零宽度非捕获)预测:\.。用空格替换它会产生你想要的结果。

如果你想只在标记之间替换句点,你可以在前面加上一个正面的后视:(?=\w)并附加一个正向前瞻:(?=。+ TOKEN2),所以完整的正则表达式将是:

(?<=TOKEN1:.+)

如果句点可以在开始令牌之后立即和/或在结束令牌之前立即发生,您可能需要对此进行优化。