字符串查找/替换算法

时间:2009-10-30 19:15:52

标签: algorithm replace

我希望能够在字符串中搜索各种单词,当我找到一个时,我想将该点的字符串拆分为3个部分(左,匹配,右),匹配的文本将被排除,并且该过程将继续使用新字符串left + right。

现在,一旦我完成所有比赛,我需要通过在被移除的位置重新插入匹配的单词(或替换它们)来反转该过程。我在任何搜索中都没有真正找到我想要的东西,所以我想我会在SO上请求输入。

如果这个问题需要进一步说明,请与我们联系。

BTW - 目前,我有一个非常糟糕的算法,用一个唯一的字符串标记替换匹配的文本,然后在所有匹配完成后用适当的匹配替换文本替换标记。

这是目标:

one two three four five six 

匹配“三”替换为foo(记住我们找到了三个,我们找到了它)

one two four five six
       |
     three

匹配“两个四”并防止它被任何东西匹配(为清晰起见而编辑)

one five six
   |
 two four 
       |
     three

此时,您无法匹配例如“一二”

已找到所有匹配项,现在将其替换项重新放入(按相反顺序)

one two four five six
       |
     three


one two foo four five six

重点是什么?防止一个匹配的替换文本与另一个模式匹配。 (对于每个处理的字符串,所有模式都在同一时间运行,并以相同的顺序运行)

我不确定语言是否重要,但在这种情况下我使用的是Lua。

我会尝试改写,我有一个我希望在给定字符串中找到的模式列表,如果我找到一个,我想删除字符串的那部分所以它不匹配其他任何东西,但我想要跟踪我找到它的位置,这样一旦我尝试匹配我的模式列表,我就可以插入替换文本

以下是相关问题:

Shell script - search and replace text in multiple files using a list of strings

4 个答案:

答案 0 :(得分:3)

您的算法说明不清楚。没有确切的规则,应该重新插入提取的标记。

以下是一个例子:

  1. 在'一二三四五六'中找到'三'
  2. 选择其中一个以获得'foo bar'作为结果:

    一个。将'one two'替换为'foo',将'four five six'替换为'bar'

    湾用'foo bar'替换'one two four five six'

  3. 在步骤2中插入“三个”后面的字符串'foo bar'

  4. 在第3步,'3'会在'bar'之前或之后吗?

    一旦你想出了重新插入的明确规则,就可以轻松地将算法实现为递归方法或带有替换堆栈的迭代方法。

答案 1 :(得分:1)

考虑到问题的结构,我可能会尝试基于二叉树的算法。

答案 2 :(得分:0)

伪代码:

for( String snippet in snippets )
{
    int location = indexOf(snippet,inputData);
    if( location != -1)
    {
        // store replacement text for a found snippet on a stack along with the
        // location where it was found
        lengthChange = getReplacementFor(snippet).length - snippet.length;
        for each replacement in foundStack
        {
            // IF the location part of the pair is greater than the location just found
            //Increment the location part of the pair by the lengthChange to account
            // for the fact that when you replace a string with a new one the location
            // of all subsequent strings will be shifted 
        }

        //remove snippet
        inputData.replace(snippet, "");
    }
}

for( pair in foundStack )
{
    inputData.insert( pair.text, pair.location);
}

这基本上就像你在问题描述中所说的完全一样。逐步执行算法,将所有内容放在堆栈中,找到它所在的位置。您使用堆栈,因此当您重新插入后半部分时,它会以相反的顺序发生,以便存储的“位置”适用于inputString的当前状态。

针对评论者的批评进行编辑。在第一个帐户中是否对您的批评进行了评论,或者在某些情况下是否仍有错误?

答案 3 :(得分:-1)

你想要做的是有一个存储输出的第二个字符串。您处理输入并在其中搜索模式。如果未找到匹配的模式,则不会进行替换,因此您只需将读入的字符直接附加到输出即可。如果找到模式,请将替换字符串附加到输出。因为你总是在字符串中向前移动,所以模式不可能匹配先前的替换。

如果你逐个字符地搜索(蛮力搜索),你必须弄清楚你想要如何区分模式的优先次序;按长度或按顺序将它们添加到模式列表中。

否则,您将逐字逐句搜索,逐句搜索,使用缓冲区进行搜索。为此,你必须确定分隔符(对于单词,它将是空格,对于句子,它将是句号感叹号和其他类似的东西,对于逗号分隔的值文件,它将是逗号)。