如何替换以一组 "special" 个字符(标签)开头和结尾的字符串

How to replace a string which starts and ends with a set of "special" characters (tags)

我有一个 Firebird 3.x 文本 blob,文本如下:

This is an {START example a=b}. The {duck} is big.

我想用 (#_____#) 替换所有 {START _____}_____ 的位置应该是“{START”和“}”之间的文本。在此示例中,结果将是:

This is an (#example a=b#). The {duck} is big.

注意"duck"后的右括号千万不要换,因为"duck"前没有"{START"。

怎么做?

像这样的事情在 Firebird 中是可能的,但做起来有点复杂。您可能需要考虑使用您选择的编程语言来执行此操作。

在 Firebird 中,您可以使用 POSITION to find the start and end marker, and then use SUBSTRING 和连接来重建字符串。

使用这些函数,您可以构建自己的 PSQL function:

create or alter function replace_tags(input_value blob sub_type text) returns blob sub_type text
as
declare temp blob sub_type text = '';
declare start_tag char(7) = '{START ';
declare end_tag char(1) = '}';
declare start_replacement char(2) = '(#';
declare end_replacement char(2) = '#)';
declare search_start integer = 1;
declare start_position integer;
declare end_position integer;
begin
    while (true) do
    begin
        -- Search for occurrence of start-tag '{START ' 
        start_position = position(start_tag, input_value, search_start);
        if (start_position = 0) then leave;
    
        -- Search for occurrence of end-tag '}' after start-tag
        end_position = position(end_tag, input_value, start_position + 7);
        if (end_position = 0) then leave;

        temp = temp
             -- Add text before start-tag (and after previous end-tag found)
             || substring(input_value from search_start for start_position - search_start)
             -- Add replacement start-tag
             || start_replacement
             -- Add text between start-tag and end-tag
             || substring(input_value from start_position + 7 for end_position - start_position - 7)
             -- Add replacement end-tag
             || end_replacement;

        -- Setup for next search or finding remainder of string
        search_start = end_position + 1;
    end
    -- Add remainder of the string
    temp = temp || substring(input_value from search_start);
    return temp;
end

我没有完全测试这个功能,所以一定要自己测试。

用法示例:

select replace_tags('This is an {START example a=b}. The {duck} is big.')
from rdb$database

输出:

This is an (#example a=b#). The {duck} is big.