如何计算多个字符串的长度

3

我有一个字符串:

嘿,我的名字是$name$; 我$years$岁了,我喜欢打$sport$并且我住在$country$!

现在我想要得到每个$符号中间单词的长度,并将其存储在一个Map中,例如我的例子中Map应该是:

  • name -> 4
  • years -> 5
  • sport -> 5
  • country -> 7

一开始我考虑在我的函数中进行递归调用,但是我找不到方法?


1
你是在询问如何提取字符串“$name$”,“$years$”等吗? - bradimus
不是真正的提取,而是如何获取这些字符串的长度。 - Clement Cuvillier
4个回答

5
您可以使用PatternMatcher进行匹配,这将返回所有匹配的实例,然后您可以遍历结果并添加到映射表中。
String x = "Hey my name is $name$; I have $years$ years old," + 
           "and I love play $sport$ and I live in $country$ !";
Pattern p = Pattern.compile("\\$\\w+\\$");
Matcher m = p.matcher(x);
Map<String, Integer> map = new LinkedHashMap<>();

while(m.find()) {
  String in = m.group().substring(1,m.group().length()-1);
  map.put(in, in.length());
}

1
这只匹配$a$中的单个字符,而且该映射将会忽略可能不希望出现的重复。 - Michael
令人惊讶的是,结果非常奇怪:一个结果丢失了,其他结果也错乱了。当我打印我的地图时,结果如下: 国家 -> 7 运动 -> 5 年份 -> 5 - Clement Cuvillier
@ClementCuvillier 对我来说,它打印出国家7、姓名4、运动5、年份5。 - Eduardo Dennis
@ClementCuvillier 看看我的新编辑,如果顺序很重要,你必须使用LinkedHashMap。 - Eduardo Dennis
一个映射并不保证任何顺序。如果您需要基于插入顺序的排序,我建议您使用其他东西。 - jiveturkey
显示剩余4条评论

1
你可以使用类似于正则表达式的语法,例如:

(.).*\1

搜索以相同字符开头和结尾的单词。

1
记住,地图不允许重复项...... 如果这对您来说没问题,那么使用流和正则表达式可以实现这一点:
String x = "Hey my name is $name$; I have $years$ years old, and I love play $sport$ and I live in $country$ !";
//regex to get the words between $
Matcher m = Pattern.compile("\\$(.*?)\\$").matcher(x);
List<String> l = new ArrayList<>();
//place those matchs in a list
while (m.find()) {
        l.add(m.group(1));
    }
System.out.println(l);
//collect those into a Map
Map<String, Integer> result = l.stream().collect(Collectors.toMap(q -> q, q -> q.length()));

System.out.println(result);

你的地图可能如下所示:

{国家=7,名称=4,运动=5,年份=5}


1
不需要使用 group(1),你可以直接使用 group() - Michael

0

你可以使用流。

public void test() {
    String s = "Hey my name is $name$; I have $years$ years old, and I love play $sport$ and I live in $country$ !";
    // Helps me maintain state of whether we are in a word or not.
    // Use AtomicBoolean as a `final` mutable value.
    final AtomicBoolean inWord = new AtomicBoolean(false);
    // Split on the `$` character and stream it.
    Map<String, Integer> myMap = Arrays.stream(s.split("\\$"))
            // Filter out the non-words (i.e. every other one).
            .filter(w -> inWord.getAndSet(!inWord.get()))
            // Generate the map.
            .collect(Collectors.toMap(w -> w, w -> String::length));
    System.out.println(myMap);
}

输出:

{国家=7,名称=4,运动=5,年份=5}


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接