正则表达式匹配从A到Z的单个字母

时间:2018-09-17 07:39:58

标签: java regex

我希望正则表达式匹配字符串中的单个字母(按顺序从A到Z):

它应该找到字母'A',如果没有'A',它应该找到字母'B',然后是'C',依此类推...

示例->

  • BCD A E

  • C B DE->由于不存在'A',因此它与B

  • 匹配
  • Y X Z

  • B A AC->由于存在两个'A',因此它找到最左边的 字符优先。


其他信息:

我将提供一个示例,因为一些用户似乎不喜欢没有代码的问题。

  

给出一个小写的字符串,从该字符串中删除k个字符。第一   删除所有字母“ a”,然后删除字母“ b”,再删除“ c”,等等。

。这是我的解决方案:

public static String remove(String s, int k) {
  for (int c : s.chars().sorted().limit(k).toArray())
    s = s.replaceFirst(Character.toString((char) c), "");
  return s;
}

但是我想使用如下正则表达式来尝试:

public static String remove(String s, int k) {
  while (k-- > 0)
    s = s.replaceFirst(MY_MAGIC_REGEX_STR, "");
  return s;
}

2 个答案:

答案 0 :(得分:3)

正则表达式可能不是适合此问题的最佳工具。我认为,最简单的方法是将输入字符串转换为字符数组,然后向下浏览该数组,跟踪最小(最小)字符是什么:

public char findLowestChar(String input) {
    char[] array = input.toCharArray();
    char chr = 'Z';     // works so long as input is non-empty
    for (int i=0; i < array.length; ++i) {
        if (array[i] < chr) {
            chr = array[i];
        }
    }
    return chr;
}

我在这里假设输入字符串中始终总是至少有一个字母A-Z。如果不是这样,并且您还想在方法内部实现此功能,则还应该处理空的输入情况。

编辑:

您刚刚改变了您的问题。但是事实证明,上面的代码仍然可以作为更新答案的一部分。现在,您可以迭代k次,并在每一步中运行上述代码以找到最低的字母。然后,执行String#replaceAll删除该字母的所有出现。

String input = "BCDAE";
// remove k=4 characters, starting with (maybe) A, from the input string
for (int k=0; k < 4 && input.length() > 0; ++k) {
    char lowest = findLowestChar(input);
    input = input.replaceAll(String.valueOf(lowest), "");
}

答案 1 :(得分:1)

以下正则表达式可根据需要工作:

(?i)A|B(?!.*[A-A])|C(?!.*[A-B])|D(?!.*[A-C])|E(?!.*[A-D])|F(?!.*[A-E])|G(?!.*[A-F])|H(?!.*[A-G])|I(?!.*[A-H])|J(?!.*[A-I])|K(?!.*[A-J])|L(?!.*[A-K])|M(?!.*[A-L])|N(?!.*[A-M])|O(?!.*[A-N])|P(?!.*[A-O])|Q(?!.*[A-P])|R(?!.*[A-Q])|S(?!.*[A-R])|T(?!.*[A-S])|U(?!.*[A-T])|V(?!.*[A-U])|W(?!.*[A-V])|X(?!.*[A-W])|Y(?!.*[A-X])|Z(?!.*[A-Y])

正则表达式由26个术语(每个字母一个术语)组成,这些术语通过交替运算符(|)串联在一起。 A(?!B)是否定的超前运算符,如果A后面不跟B,则匹配A。(?i)仅触发不区分大小写。

总的来说,正则表达式首先从左到右查找所有A,而不是从左到右查找所有B,依此类推。

由于正则表达式的长度,以编程方式生成它更容易:

// Generate regEx
String regEx = "(?i)" + "A" + "|";  
for (char i = 'B'; i <= 'Z'; i++ ) {
    regEx += i + "(?!.*[A-" + (char)(i-1) + "])" + "|";
}
regEx = regEx.substring(0, regEx.length() - 1);
System.out.println(regEx);

对于以下示例:

String example = "AAAZZZHHAAAZZHHHAAZZZHH"; 

// Output
while(example.length() != 0) {
    System.out.println(example);
    example = example.replaceFirst(regEx, "");
}

输出为:

AAAZZZHHAAAZZHHHAAZZZHH
AAZZZHHAAAZZHHHAAZZZHH
AZZZHHAAAZZHHHAAZZZHH
ZZZHHAAAZZHHHAAZZZHH
ZZZHHAAZZHHHAAZZZHH
ZZZHHAZZHHHAAZZZHH
ZZZHHZZHHHAAZZZHH
ZZZHHZZHHHAZZZHH
ZZZHHZZHHHZZZHH
ZZZHZZHHHZZZHH
ZZZZZHHHZZZHH
ZZZZZHHZZZHH
ZZZZZHZZZHH
ZZZZZZZZHH
ZZZZZZZZH
ZZZZZZZZ
ZZZZZZZ
ZZZZZZ
ZZZZZ
ZZZZ
ZZZ
ZZ
Z