检查子串是否在忽略大写、小写和特殊字符的字符串中?
Check If a substring is in a string ignoring uppercase, lowercase and special characters?
我正在尝试检查 "Homemade Pizza!" 之类的短语是否包含 "pizza" 之类的字符串,但我希望它始终为真,是否无关紧要这是披萨或披萨或披萨!或披萨!
我来解释一下代码:
recipesFounded
是一个包含标题、描述等的数组。这就是为什么我把 recipesFounded.get(i).getTitle()
.
问题是我有 "Homemade Pizza!" 字符串,所以如果我搜索 "Pizza!" 很好,因为食谱已添加到 trueOnes
新食谱列表中,但如果我搜索披萨(没有 mayus P 和!)它没有。
这个词是我要搜索的字符串(pizza, Pizza!...)
for (int i=0; i < recipesFounded.size(); i++) {
if (recipesFounded.get(i).getTitle().contains(word)) {
trueOnes.add(recipesFounded.get(i));
}
}
使用String
的toLowerCase
方法
word = word.replaceAll("[^a-zA-Z]","").toLowerCase(); // keep only letters
根据 Andreas 的建议,在循环之前将单词转换为小写。效率更高。
for (int i=0; i < recipesFounded.size(); i++) {
if (recipesFounded.get(i).getTitle().toLowerCase()
.contains(word)) {
trueOnes.add(recipesFounded.get(i));
}
}
由于List
实现了iterable
接口,你可以这样操作。它假定您正在使用一个名为 Recipe
的 class
for (Recipe recipe : recipesFounded) {
if (recipe.getTitle().toLowerCase()
.contains(word)) {
trueOnes.add(recipe);
}
}
为了按给定顺序搜索 letters/digits,忽略大小写、空格和特殊字符,最好将搜索字符串转换为 常规表达式.
要允许搜索字符串 "foobar"
与 "Foo-Bar"
匹配,我们需要在任何字母数字字符之间允许特殊字符。
为了完全支持 Unicode,我们将使用 \p{Alnum}
and flags UNICODE_CHARACTER_CLASS
, CASE_INSENSITIVE
, and UNICODE_CASE
,或者更确切地说,大写 P
表示非字母数字。
匹配例如A
与 Á
,我们还 分解 Unicode 字符,使用 Normalizer.normalize(str, Normalizer.Form.NFD)
.
这是一个如何做到这一点的例子:
static List<String> search(List<String> texts, String word) {
String regex = Normalizer.normalize(word, Normalizer.Form.NFD) // e.g. "Á" -> "A\u0301"
.replaceAll("(?U)\P{Alnum}+", "") // e.g. "I'm!" -> "Im"
.replaceAll("(?<=.)(?=.)", "\\P{Alnum}*"); // insert '\P{Alnum}*' between all characters
Pattern p = Pattern.compile(regex, Pattern.UNICODE_CHARACTER_CLASS |
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
List<String> trueOnes = new ArrayList<>();
for (String text : texts) {
if (p.matcher(Normalizer.normalize(text, Normalizer.Form.NFD)).find()) {
trueOnes.add(text);
}
}
return trueOnes;
}
测试
List<String> texts = List.of("Homemade Pizza!", "Dessert", "Pizza Hut", "Potato-Söûp", "O'Malleys Ale");
System.out.println(search(texts, "pizza")); // [Homemade Pizza!, Pizza Hut]
System.out.println(search(texts, "made, pi")); // [Homemade Pizza!]
System.out.println(search(texts, "ömÁl")); // [O'Malleys Ale]
System.out.println(search(texts, "TOSO")); // [Potato-Söûp]
我正在尝试检查 "Homemade Pizza!" 之类的短语是否包含 "pizza" 之类的字符串,但我希望它始终为真,是否无关紧要这是披萨或披萨或披萨!或披萨!
我来解释一下代码:
recipesFounded
是一个包含标题、描述等的数组。这就是为什么我把 recipesFounded.get(i).getTitle()
.
问题是我有 "Homemade Pizza!" 字符串,所以如果我搜索 "Pizza!" 很好,因为食谱已添加到 trueOnes
新食谱列表中,但如果我搜索披萨(没有 mayus P 和!)它没有。
这个词是我要搜索的字符串(pizza, Pizza!...)
for (int i=0; i < recipesFounded.size(); i++) {
if (recipesFounded.get(i).getTitle().contains(word)) {
trueOnes.add(recipesFounded.get(i));
}
}
使用String
toLowerCase
方法
word = word.replaceAll("[^a-zA-Z]","").toLowerCase(); // keep only letters
根据 Andreas 的建议,在循环之前将单词转换为小写。效率更高。
for (int i=0; i < recipesFounded.size(); i++) {
if (recipesFounded.get(i).getTitle().toLowerCase()
.contains(word)) {
trueOnes.add(recipesFounded.get(i));
}
}
由于List
实现了iterable
接口,你可以这样操作。它假定您正在使用一个名为 Recipe
for (Recipe recipe : recipesFounded) {
if (recipe.getTitle().toLowerCase()
.contains(word)) {
trueOnes.add(recipe);
}
}
为了按给定顺序搜索 letters/digits,忽略大小写、空格和特殊字符,最好将搜索字符串转换为 常规表达式.
要允许搜索字符串 "foobar"
与 "Foo-Bar"
匹配,我们需要在任何字母数字字符之间允许特殊字符。
为了完全支持 Unicode,我们将使用 \p{Alnum}
and flags UNICODE_CHARACTER_CLASS
, CASE_INSENSITIVE
, and UNICODE_CASE
,或者更确切地说,大写 P
表示非字母数字。
匹配例如A
与 Á
,我们还 分解 Unicode 字符,使用 Normalizer.normalize(str, Normalizer.Form.NFD)
.
这是一个如何做到这一点的例子:
static List<String> search(List<String> texts, String word) {
String regex = Normalizer.normalize(word, Normalizer.Form.NFD) // e.g. "Á" -> "A\u0301"
.replaceAll("(?U)\P{Alnum}+", "") // e.g. "I'm!" -> "Im"
.replaceAll("(?<=.)(?=.)", "\\P{Alnum}*"); // insert '\P{Alnum}*' between all characters
Pattern p = Pattern.compile(regex, Pattern.UNICODE_CHARACTER_CLASS |
Pattern.CASE_INSENSITIVE | Pattern.UNICODE_CASE);
List<String> trueOnes = new ArrayList<>();
for (String text : texts) {
if (p.matcher(Normalizer.normalize(text, Normalizer.Form.NFD)).find()) {
trueOnes.add(text);
}
}
return trueOnes;
}
测试
List<String> texts = List.of("Homemade Pizza!", "Dessert", "Pizza Hut", "Potato-Söûp", "O'Malleys Ale");
System.out.println(search(texts, "pizza")); // [Homemade Pizza!, Pizza Hut]
System.out.println(search(texts, "made, pi")); // [Homemade Pizza!]
System.out.println(search(texts, "ömÁl")); // [O'Malleys Ale]
System.out.println(search(texts, "TOSO")); // [Potato-Söûp]