我有一个像这样的字符串列表"出租车或公共汽车司机"。我需要将每个单词的第一个字母转换为大写字母,除了单词"或" 。有没有简单的方法来使用Java流来实现这一点。 我尝试过使用Pattern.compile.splitasstream技术,我无法将所有分裂的标记连接起来形成原始字符串 如果有任何身体需要,我可以在这里发布我的代码。
答案 0 :(得分:3)
您需要正确的模式来识别必须进行更改的位置,当您想要使用splitAsStream
时,需要零宽度模式。匹配位置
声明它就像
static final Pattern WORD_START_BUT_NOT_OR = Pattern.compile("\\b(?=\\p{Ll})(?!or\\b)");
然后,使用它来处理令牌是直截了当的流和map
。获取字符串可以通过.collect(Collectors.joining())
:
List<String> input = Arrays.asList("Taxi or bus driver", "apples or oranges");
List<String> result = input.stream()
.map(s -> WORD_START_BUT_NOT_OR.splitAsStream(s)
.map(w -> Character.toUpperCase(w.charAt(0))+w.substring(1))
.collect(Collectors.joining()))
.collect(Collectors.toList());
result.forEach(System.out::println);
Taxi or Bus Driver
Apples or Oranges
请注意,拆分时,无论是否符合条件,都会有第一个令牌。由于单词“or”通常不会出现在短语的开头,并且转换对非小写字母字符是透明的,因此这不应该是一个问题。否则,使用流特殊处理第一个元素会使代码过于复杂。如果这是一个问题,那么循环将更可取。
基于循环的解决方案可能看起来像
private static final Pattern FIRST_WORD_CHAR_BUT_NOT_OR
= Pattern.compile("\\b(?!or\\b)\\p{Ll}");
(现在使用与角色匹配的模式而不是查看它)
public static String capitalizeWords(String phrase) {
Matcher m = FIRST_WORD_CHAR_BUT_NOT_OR.matcher(phrase);
if(!m.find()) return phrase;
StringBuffer sb = new StringBuffer();
do m.appendReplacement(sb, m.group().toUpperCase()); while(m.find());
return m.appendTail(sb).toString();
}
作为奖励,它还能够处理跨越多个char
单位的字符。从Java 9开始,StringBuffer
可以替换为StringBuilder
以提高效率。此方法可以像
List<String> result = input.stream()
.map(s -> capitalizeWords(s))
.collect(Collectors.toList());
也可以使用s -> capitalizeWords(s)
形式的方法引用替换lambda表达式ContainingClass::capitalizeWords
。
答案 1 :(得分:2)
这是我的代码:
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class ConvertToCapitalUsingStreams {
// collection holds all the words that are not to be capitalized
private static final List<String> EXCLUSION_LIST = Arrays.asList(new String[]{"or"});
public String convertToInitCase(final String data) {
String[] words = data.split("\\s+");
List<String> initUpperWords = Arrays.stream(words).map(word -> {
//first make it lowercase
return word.toLowerCase();
}).map(word -> {
//if word present in EXCLUSION_LIST return the words as is
if (EXCLUSION_LIST.contains(word)) {
return word;
}
//if the word not present in EXCLUSION_LIST, Change the case of
//first letter of the word and return
return Character.toUpperCase(word.charAt(0)) + word.substring(1);
}).collect(Collectors.toList());
// convert back the list of words into a single string
String finalWord = String.join(" ", initUpperWords);
return finalWord;
}
public static void main(String[] a) {
System.out.println(new ConvertToCapitalUsingStreams().convertToInitCase("Taxi or bus driver"));
}
}
注意: 您可能还想查看有关使用apache commons-text library执行此工作的SO帖子。
答案 2 :(得分:1)
你可以这样做,
final List<String> firstLetterCapitalized = driverOptions.stream().map(line -> Stream.of(line.split(" "))
.map(token -> token.equals("or") ? token : Character.toUpperCase(token.charAt(0)) + token.substring(1))
.collect(Collectors.joining(" "))).collect(Collectors.toList());
答案 3 :(得分:1)
将字符串拆分为单词,然后将第一个字符转换为大写,然后将joining
转换为原始字符串:
String input = "Taxi or bus driver";
String output = Stream.of(input.split(" "))
.map(w -> {
if (w.equals("or") || w.length() == 0) {
return w;
}
return w.substring(1) + Character.toUpperCase(w.charAt(0));
})
.collect(Collectors.joining(" "));