匹配字符数组的单词开头?

时间:2014-08-26 16:51:14

标签: regex

我想使用正则表达式来匹配给定一组字符的字符串中单词的开头。

考虑一下:

string = "abcd ab def"
match = ["a", "b", "d"]

从那以后,我希望它与ab中的abcdd中的def匹配,而abab中的a匹配我们已经有一个以/(\babd)|(\bab)|(\ba)|(\bbd)|(\bb)|(\bd)/gi 开头的匹配。

我尝试了以下内容:

ab
除了a也匹配的事实之外,

哪种作品。我理解为什么它匹配,并且它应该,鉴于我的正则表达式。但是,我不知道如何使它与仅以abd开头的单词匹配一次。

基本上,我想要的是给定字符a,我希望匹配以ab开头的第一个字,以及它是否也匹配abd和/或{{ 1}}。在此之后,我只想要以b开头的单词的第一个匹配项以及是否也与bd匹配。最后,我希望首先匹配以d开头的单词。

迭代匹配并且只保留任何给定字符的第一个匹配将非常容易,但我更愿意直接在正则表达式中解决它。

为了让它更有趣,请考虑一下:

string = "abcd ab def bd"
match = ["a", "b", "d"]

这也匹配bd,但我不想要,因为b中的abd已用完了#34}。在第一场比赛中。

如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

如果你的正则表达式引擎支持lookbehind assertions内的无限重复,这是可能的,所以你几乎只限于.NET或JGSoft引擎:

(?<!\b\1.*)\b(ab|d)

<强>解释

(?<!    # Make sure it's impossible to match *before* the current position
 \b     # the start of a word
 \1     # and the match of the capturing group 1
 .*     # followed by any number of characters
)       # End of lookbehind assertion
\b      # Match a start of a word
(ab|d)  # Match (and capture in group 1) either "ab" or "d"

修改

由于您现在已将语言指定为Java,因此正则表达式解决方案将无效。你的第二个案例是不可能用正则表达式实现的,因为正则表达式引擎无论如何都不会在各个正则表达式匹配中保持状态,因此无法阻止bd匹配。你需要一个程序化的解决方案,幸运的是,它是相当微不足道的。我不是Java人员,但以下Python脚本应该是非常易读的:

string = "abcd ab def bd"
match = {"a", "b", "d"}   # Set of all characters to be considered
words = string.split()    # Split string on whitespace
result = []
for word in words:        # Python's for is like Java's foreach
    add = False
    for letter in word:
        if letter in match:
            add = True
            match.remove(letter)
        else:
            break
    if add:
        result.append(word)

result['abcd', 'def']