我正在尝试查找给定字符串上每个字符的出现次数。
t=2 e=1 s=1 i=1 n=1 g=1
T=0 e=0 s=0 t=0 i=0 n=0 g=0
代码:
String str = "Testing";
int count = 0;
Pattern p = Pattern.compile("[a-zA-Z]", Pattern.CASE_INSENSITIVE);
Matcher m = p.matcher(str);
while (m.find()) {
if (m.group().equals(str)) {
count++;
}
System.out.println(m.group() + "=" + count);
}
有很多方法可以做到这一点,但是我只在寻找Regex,所以我们如何使用Regex来实现这一目标。任何帮助,将不胜感激。预先感谢。
答案 0 :(得分:3)
不需要正则表达式来解决您的问题,如果您使用的是Java8 +,则可以使用:
String input = "Testing";
Map<String, Long> result = Arrays.stream(input.split(""))
.map(String::toLowerCase)
.collect(Collectors.groupingBy(s -> s, LinkedHashMap::new, Collectors.counting()));
输出
{t=2, e=1, s=1, i=1, n=1, g=1}
编辑
mmm,在这种情况下,Pattern是无用的,我不建议在此问题中使用它,作为使用Pattern9和Java9 +结果的替代解决方案,您可以使用:
String str = "Testing";
Pattern.compile(".").matcher(str)
.results()
.map(m -> m.group().toLowerCase())
.collect(Collectors.groupingBy(s -> s, LinkedHashMap::new, Collectors.counting()))
.forEach((k, v) -> System.out.println(k + " = " + v));
输出
t = 2
e = 1
s = 1
i = 1
n = 1
g = 1
答案 1 :(得分:3)
有很多方法可以达到目的,但是Regex并不是实现这一目标的工具。如果要过滤字符并确保仅计算[a-zA-Z]
,请使用string = string.replaceAll("[^a-zA-Z]", "");
过滤不需要的字符。现在回到您的问题。
您需要将String
拆分为字符,然后Map<Character, Integer>
将存储这些字符及其出现的次数。我建议您使用LinkedHashMap<Character, Integer>
来确保插入顺序。
char[] charArray = string.toCharArray();
Map<Character, Integer> map = new LinkedHashMap<>();
现在循环浏览角色并将其保存到地图。如果已经存储了一个字符,则将该值加1。这可以通过程序和传统的for-loop
来实现,或者由于Java 8您可以使用java-stream。
在Java 8之前:
for (char ch: charArray) {
if(map.containsKey(ch)){
map.put(ch, map.get(ch)+1);
} else {
map.put(ch, 1);
}
}
Java 8之后(string.split("")
返回一个字符串数组,您需要将它们映射为字符):
Map<Character, Long> map = Arrays
.asList(string.split("")).stream().map(s -> s.charAt(0))
.collect(Collectors.groupingBy(s -> s, LinkedHashMap::new, Collectors.counting()));
在两种情况下,输出都将相同:
System.out.println(map); // prints {t=2, e=1, s=1, i=1, n=1, g=1}