Regex以替换特定令牌中出现的所有单个字符


Regex to replace all occurrences of single character within specific tokens

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

例如,是否可以将TOKEN1&TOKEN2,如下例所示?

因此:

TOKEN1:Run.Spot.run:TOKEN2

更改为:

TOKEN1:Run Spot run:TOKEN2

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

我问这个问题更多的是为了我个人的知识,因为这是我过去在各种regex实现中多次想要做的事情。然而,在这种特殊情况下,regex将在php中。

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

感谢

一种方法:

$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:之后将替换所有'.字符。

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

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

(免责声明:未测试。)

最简单的方法是,您需要一个转义(')句点(因为句点通常与任何字符匹配)作为您的模式:'.,然后用空格替换它:

这将用替换(?<='w)的所有实例。

然而,从您的评论中,您似乎要求使用正则表达式来替换单词字符之间的所有句点:

(?<='w)'.(?='w)

对于单词字符(?='w)、转义周期((?<=TOKEN1:.+)),您需要一个正的(零宽度非捕获)后向查找,对于单词字符:CCD_13,则需要一个正向的(零宽非捕获)前向查找。用空格替换它会得到您想要的结果。

如果您只想替换令牌之间的句点,您可以在前面加上一个正的lookbacking:CCD_14,然后再加上一条正的lookahead:(?=.+TOKEN2),因此完整的正则表达式为:

(?<=TOKEN1:.+)(?<='w)'.(?='w)(?=.+TOKEN2)

如果句点可能出现在开始标记之后和/或结束标记之前,并且您不想替换它们,则可能需要对此进行细化。