正则表达式查找所有子字符串和最长子字符串

本文关键字:字符串 查找 正则表达式 | 更新日期: 2023-09-27 18:01:54

我通常会使用字符串库做这样的事情。但是我想知道是否可以使用正则表达式来完成。

我想做以下事情:给定搜索字符串:

西雅图真棒

我想在给定的句子中找到

的所有子字符串。因此,将正则表达式应用于以下句子

西雅图西雅图很棒很棒很棒很棒西雅图

应该给我

西雅图,西雅图是很棒的,是很棒的,很棒的,是,西雅图

一个可能有帮助的约束是句子将始终只包含搜索字符串中出现的单词和中间的空白。

注意如果有匹配,它应该是最长的字符串。因此,像上面的例子一样,匹配不应该是单个单词,而应该是最长的子字符串。单词之间的顺序也需要保持。这就是为什么

awesome is Seattle

上面句子中的

给了我们

awesome, is and Seattle

我不确定这样的事情是否可以用正则表达式完成,因为它是贪婪的。我很感激任何对此的见解!我熟悉c#和Java,可以使用它们的正则表达式库中的任何一个。

正则表达式查找所有子字符串和最长子字符串

我不认为你可以用正则表达式做到这一点。维基百科上有一篇关于最长公共子序列问题的好文章。

没有好的方法可以直接用正则表达式表示这种模式。

你需要列出所有允许的组合:

<>之前西雅图好棒!西雅图好棒!西雅图好棒之前

或者更简洁地说:

<>之前西雅图很棒吗?|(棒)吗?|太棒了之前

您可以通过编程方式将您的输入字符串转换为此格式。

你能进一步描述一下你的问题吗?它听起来更像是一个搜索引擎,而不是简单的字符串匹配。我强烈推荐你看看Apache Lucene——它有一点学习曲线,但它是一个很棒的智能搜索工具。它处理了很多在处理搜索时遇到的问题。

在Java中,未被测试。这将返回一个字符串列表的迭代器。每个列表都是一个匹配子序列。只需在要打印的列表的成员之间加上空格。如果经常使用,那么使用intern()可能是不好的。

static Iterator<List<String>> getSequences(String squery, String starget)
{
    List<String> query = Arrays.asList(squery.split(" "));
    for ( int i = 0; i < query.size(); i++)
        query.set(i, query.get(i).intern());
    List<String> target = Arrays.asList(starget.split(" "));;
    for ( int i = 0; i < target.size(); i++)
        target.set(i, target.get(i).intern());
    // Because the strings are all intern'ed, this HashSet acts like we want -
    // If two lists are the same sequence of words, they are equal.
    // It's used to remove duplicates.
    HashSet<List<String>> ret = new HashSet<List<String>>();
    for ( int qBegin = 0; qBegin < query.size(); qBegin++ )     {
        for ( int tBegin = 0; tBegin < target.size(); tBegin++ ) {
            for ( int iCursor = 0; 
                  iCursor < min(query.size()-qBegin, target.size()- tBegin); 
                  iCursor++)                {
                if ( query.get(qBegin+iCursor)==target.get(tBegin+iCursor) )
                    ret.add(query.subList(qBegin, qBegin+iCursor+1));
                else break;
            }
        }
    }
    return ret.iterator();
}
static int min(int a, int b) { return (a<b)? a:b; }