我可以匹配单词的开头吗?

时间:2012-06-11 20:50:42

标签: regex pattern-matching

我正在构建一个小型过滤器实用程序,供用户快速过滤项目列表,我希望按顺序匹配单词的开头,最好使用正则表达式:

考虑用户尝试查找标有here is some text的项目。

  • 我已经知道如何使它与任何一个单词的开头相匹配:

- e是一些文字 - \bher
所以 - 这是所以我的文字 - \bso
分机 - 不匹配 - \bext

  • 而且我知道如何使它与几个单词的第一个字母相匹配:

hist - h ere s s ome t 分机 - { {1}}
ht - h ere是一些 t 分机 - \bh.*?\bi.*?\bs.*?\bt

  • 我需要的是能够匹配多个单词的第一个\bh.*?\bt字符:

赫斯特 - e s ome t \ n \ n> iso - 这里 s 所以我的文字
teh - 不匹配

我这样做是因为我的项目通常包含初始内容,用户可以输入 usc 来尝试快速拉出 US A, C alifornia

我正在为每个输入重写模式,所以我可以做一些工作,如果#2中的必要。我正在寻找一种解决方案,它可以在模式复杂度或总复杂度方面与字符数进行线性扩展。

鉴于这些限制,匹配这些字符串的最佳选择是什么?

4 个答案:

答案 0 :(得分:2)

我不认为这对标准的正则表达式库是可行的。

但是考虑到你的约束,你应该能够编写自己的解析器来进行匹配。保留一叠模式,然后从头开始扫描输入文本。您需要跟踪的唯一状态是前一个字符是边界还是从堆栈中取出一个项目。如果你在没有清空堆栈的情况下到达输入的末尾,那就是不匹配。

在伪代码中:

pattern = "herst"
input = "here is some text"
state = true
until input.empty? or pattern.empty? do
  if input[0] == pattern[0] and state
    pattern.shift!
  else
    state = is_boundary(input[0])
  endif
  input.shift!
done
return pattern.empty?

答案 1 :(得分:1)

Monstrosities喜欢:

 \bh(.*?\b)?e(.*?\b)?r(.*?\b)?s(.*?\b)?t

基本上,每个字母前面都有前一个字母,或者以字边界(.*?\b)结尾的随机序列。因此,我们使用?使这个随机序列+ \ b可选。因此,在所有字母之间用(.*?\b)?分解它应该有效。

答案 2 :(得分:0)

使用纯正的regexp以灵活的方式执行此操作即使不是不可能,也很困难。我遇到的一种可能的方法是首先尝试使用字边界进行简单的正则表达式匹配,然后生成一组所有可能的前缀和后缀对并与之匹配。但是,如果您希望能够在字符串中任意匹配两个以上单独的单词,则应该编写一个简单的函数,遍历要搜索的字符串,尝试匹配查询字符串中的最长前缀。一旦找到最长的前缀,就转到搜索字符串中的下一个单词,并尝试匹配查询的其余部分(即减去已匹配的前缀),并继续执行此操作直到整个查询已匹配,或搜索的字符串结束。这应该很容易递归实现。

答案 3 :(得分:-2)

尝试使用^<myregex>作为字符串的开头,并<myregex>$作为结尾。