通过前缀匹配单词

问题描述 投票:0回答:5

我正在尝试通过以特定字符结尾的前缀来匹配字符串。例如,如果我的字符串是"abcd"并以#结尾,则任何以"abcd"为前缀的单词都应匹配,只要它以#结尾即可。这里有一些例子来帮助说明这种模式:

输入"ab#"给出true(因为"ab""abcd"的前缀并以#结尾)。

输入"abcd#"给出true(因为"abcd""abcd"的前缀并以#结尾)。

输入"bc#"给出false(因为"bc"不是"abcd"prefix。)

Input"ab@"给出false"ab""abcd"prefix,但不以#结尾)。

输入"ac#"给出false(虽然"ac"包含在"abcd"中,但它并不以"abcd"的前缀开头)。

到目前为止,我已经设法提出了下面的表达式,该表达式似乎运行良好:

/(abcd|abc|ab|a)#/

虽然这是可行的,但不是很实用,因为较大的单词n会使表达式变得很大:

/(n|n-1|n-2| ... |1)#/

是否有方法可以重写此表达式,使其更具伸缩性和简洁性?

我的尝试示例(使用JS):

const regex = /(abcd|abc|ab|a)#/; 

console.log(regex.test("abcd#")); // true
console.log(regex.test("ab#")); // true
console.log(regex.test("abc#")); // true
console.log(regex.test("abz#")); // false
console.log(regex.test("abc@")); // false

Edit:提供的某些解决方案很好,可以满足我的要求,但是,对于这个特定问题,我正在寻求使用纯正则表达式来匹配前缀的解决方案。

regex prefix
5个回答
3
投票

仅在此处使用String#startsWithString#endsWith

String input = "abcd";
String prefix = "ab#";

if (input.startsWith(prefix.replaceAll("#$", "")) && prefix.endsWith("#")) {
    System.out.println("MATCH");
}
else {
    System.out.println("NO MATCH");
}

Edit:上面的JavaScript版本:

var input = "abcd";
var prefix = "ab#";

if (input.startsWith(prefix.replace(/#$/, "")) && prefix.endsWith("#")) {
   console.log("MATCH");
}
else {
    console.log("NO MATCH");
}

1
投票

尝试^ab?c?d?#$

说明:

`^` - match beginning of a string

`b?` - match match zero or one `b`

休息与上述类似。

Demo


1
投票

这是一个左侧字段JavaScript选项。构建和构建有效前缀的数组,在该数组上使用join来创建您的正则表达式模式。

var validPrefixes = ["abcd",
"abc", 
"ab", 
"a", 
"areallylongprefix"];

var regexp = new RegExp("^(" + validPrefixes.join("|") + ")#$");


console.log(regexp.test("abcd#"));// true
console.log(regexp.test("ab#")); // true
console.log(regexp.test("abc#")); // true
console.log(regexp.test("abz#")); // false
console.log(regexp.test("abc@")); // false
console.log(regexp.test("areallylongprefix#")); //true

这可以适应旅行选择的语言,如果您的前缀是从数据库或类似的数据库中动态检索出来的,也很方便。


0
投票

这是我的C#尝试:

private static bool test(string v)
{
   var pattern = "abcd#";
   //No error handling
   return v.EndsWith(pattern[pattern.Length-1])
      && pattern.Replace("#", "").StartsWith(v.Replace("#",""));
}
Console.WriteLine(test("abcd#")); // true
Console.WriteLine(test("ab#")); // true
Console.WriteLine(test("abc#")); // true
Console.WriteLine(test("abz#")); // false
Console.WriteLine(test("abc@")); // false
Console.WriteLine(test("abc")); //false

0
投票
/a(b(cd?)?)?#/

或者对于更长的例子,匹配前缀“ abcdefg#”:

/a(b(c(d(e(fg?)?)?)?)?)?#/

生成此正则表达式并不完全是琐碎的,但是有些选择是:

function createPrefixRegex(s) {
    // This method creates an unnecessary set of parentheses
    // around the last letter, but that won't harm anything.
    return new RegExp(s.slice(0,-1).split('').join('(') + ')?'.repeat(s.length - 2) + '#');
}

function createPrefixRegex2(s) {
    var r = s[0];
    for (var i = 1; i < s.length - 2; ++i) {
        r += '(' + s[i];
    }
    r += s[s.length - 2] + '?' + ')?'.repeat(s.length - 3) + '#';
    return new RegExp(r);
}

function createPrefixRegex3(s) {
    var recurse = function(i) {
        if (i >= s.length - 1) {
            return '';
        }
        if (i === s.length - 2) {
            return s[i] + '?';
        }   
        return '(' + s[i] + recurse(i + 1) + ')?';
    }   

    return new RegExp(s[0] + recurse(1) + '#');
}

如果输入字符串在'#'字符之前没有前缀,并且它们假定字符串中的最后一个字符为'#',则这些命令可能会失败。

© www.soinside.com 2019 - 2024. All rights reserved.