How to find nth occurrence of character in a string?
与此处发布的问题类似,正在寻找
Java解决方案。
也就是说,如何从字符串中找到第n个出现的字符/字符串的索引?
示例:" / folder1 / folder2 / folder3 /"。
在这种情况下,如果我要求第三次出现斜杠(/),它会出现在folder3之前,并且我希望返回该索引位置。 我的实际意图是从字符的第n次出现开始对它进行子串化。
Java API中是否有任何方便/易于使用的方法,还是我们需要自己编写一个小的逻辑来解决这个问题?
也,
如果您的项目已经依赖于Apache Commons,则可以使用
1 2 3 4 5 6 |
这篇文章在这里已被重写为文章。
我认为查找字符串的第N个最简单的解决方案是使用来自Apache Commons的StringUtils.ordinalIndexOf()。
例:
1 | StringUtils.ordinalIndexOf("aabaabaa","b", 2) == 5 |
发生两个简单的选择:
-
重复使用
charAt() -
重复使用
indexOf()
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public static int nthIndexOf(String text, char needle, int n) { for (int i = 0; i < text.length(); i++) { if (text.charAt(i) == needle) { n--; if (n == 0) { return i; } } } return -1; } |
这可能不如重复使用
您可以尝试如下操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { System.out.println(from3rd("/folder1/folder2/folder3/")); } private static Pattern p = Pattern.compile("(/[^/]*){2}/([^/]*)"); public static String from3rd(String in) { Matcher m = p.matcher(in); if (m.matches()) return m.group(2); else return null; } } |
请注意,我在正则表达式中做了一些假设:
- 输入路径是绝对路径(即以" /"开头);
- 您不需要结果中的第三个" /"。
根据评论的要求,我将尝试解释正则表达式:
-
/[^/]* 是/ ,后跟[^/]* (不是/ 的任意数量的字符), -
(/[^/]*) 将先前的表达式归为一个实体。这是表达式的第x10组, -
(/[^/]*){2} 表示该组必须完全匹配{2} 次, -
[^/]* 同样是任意数量的不是/ 的字符, -
([^/]*) 将previos表达式分组在一个实体中。这是表达式的2 组。
这样,您只需要获取与第二个组匹配的子字符串即可:
图片由Debuggex提供
我对aioobe的答案进行了一些更改,并获得了第n个lastIndexOf版本,并修复了一些NPE问题。参见下面的代码:
1 2 3 4 5 6 7 8 | public int nthLastIndexOf(String str, char c, int n) { if (str == null || n < 1) return -1; int pos = str.length(); while (n-- > 0 && pos != -1) pos = str.lastIndexOf(c, pos - 1); return pos; } |
1 | ([.^/]*/){2}[^/]*(/) |
匹配后跟/两次,然后再次匹配。第三个是你想要的
Matcher状态可以用来告诉最后一个/在哪里
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
如今,已经支持Apache Commons Lang的StringUtils,
这是原始的:
1 | int org.apache.commons.lang.StringUtils.ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal) |
对于您的问题,可以编写以下代码:
您还可以使用lastOrdinalIndexOf方法在字符串中找到字符的最后n个出现位置。
可能您也可以通过String.split(..)方法实现此目的。
此答案在@aioobe的答案上有所改进。该错误的两个错误是固定的。
1. n = 0应该返回-1。
2.第n个事件返回-1,但它在第n-1个事件中起作用。
尝试这个 !
1 2 3 4 5 6 7 8 9 | public int nthOccurrence(String str, char c, int n) { if(n <= 0){ return -1; } int pos = str.indexOf(c, 0); while (n-- > 1 && pos != -1) pos = str.indexOf(c, pos+1); return pos; } |
另一种方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public static void main(String[] args) { String str ="/folder1/folder2/folder3/"; int index = nthOccurrence(str, '/', 3); System.out.println(index); } public static int nthOccurrence(String s, char c, int occurrence) { return nthOccurrence(s, 0, c, 0, occurrence); } public static int nthOccurrence(String s, int from, char c, int curr, int expected) { final int index = s.indexOf(c, from); if(index == -1) return -1; return (curr + 1 == expected) ? index : nthOccurrence(s, index + 1, c, curr + 1, expected); } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class Sam_Stringnth { public static void main(String[] args) { String str="abcabcabc"; int n = nthsearch(str, 'c', 3); if(n<=0) System.out.println("Character not found"); else System.out.println("Position is:"+n); } public static int nthsearch(String str, char ch, int n){ int pos=0; if(n!=0){ for(int i=1; i<=n;i++){ pos = str.indexOf(ch, pos)+1; } return pos; } else{ return 0; } } } |
// scala
//如果第n-1次不存在该值,则抛出-1,即使该值直到第n-1次也存在。
//如果第n次出现该值,则抛出该索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | def indexOfWithNumber(tempString:String,valueString:String,numberOfOccurance:Int):Int={ var stabilizeIndex=0 var tempSubString=tempString var tempIndex=tempString.indexOf(valueString) breakable { for ( i <- 1 to numberOfOccurance) if ((tempSubString.indexOf(valueString) != -1) && (tempIndex != -1)) { tempIndex=tempSubString.indexOf(valueString) tempSubString=tempSubString.substring(tempIndex+1,tempSubString.size) // ADJUSTING FOR 0 stabilizeIndex=stabilizeIndex+tempIndex+1 // ADJUSTING FOR 0 } else { stabilizeIndex= -1 tempIndex= 0 break } } stabilizeIndex match { case value if value <= -1 => -1 case _ => stabilizeIndex-1 } // reverting for adjusting 0 previously } indexOfWithNumber("bbcfgtbgft","b",3) // 6 indexOfWithNumber("bbcfgtbgft","b",2) //1 indexOfWithNumber("bbcfgtbgft","b",4) //-1 indexOfWithNumber("bbcfgtbcgft","bc",1) //1 indexOfWithNumber("bbcfgtbcgft","bc",4) //-1 indexOfWithNumber("bbcfgtbcgft","bc",2) //6 |
我的解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /** * Like String.indexOf, but find the n:th occurance of c * @param s string to search * @param c character to search for * @param n n:th character to seach for, starting with 1 * @return the position (0-based) of the found char, or -1 if failed */ public static int nthIndexOf(String s, char c, int n) { int i = -1; while (n-- > 0) { i = s.indexOf(c, i + 1); if (i == -1) break; } return i; } |
该代码返回第n个出现位置子字符串(也称为字段宽度)。例。如果字符串" Stacklowing in low melow"是用于搜索令牌" low"的第二次出现的字符串,则您将与我同意,第二次出现在子代" 18和21"处。 indexOfOccurance("低溢出堆栈中的堆栈",低,2)在字符串中返回18和21。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | class Example{ public Example(){ } public String indexOfOccurance(String string, String token, int nthOccurance) { int lengthOfToken = token.length(); int nthCount = 0; for (int shift = 0,count = 0; count < string.length() - token.length() + 2; count++, shift++, lengthOfToken++) if (string.substring(shift, lengthOfToken).equalsIgnoreCase(token)) { // keeps count of nthOccurance nthCount++; if (nthCount == nthOccurance){ //checks if nthCount == nthOccurance. If true, then breaks return String.valueOf(shift)+"" +String.valueOf(lengthOfToken); } } return"-1"; } public static void main(String args[]){ Example example = new Example(); String string ="the man, the woman and the child"; int nthPositionOfThe = 3; System.out.println("3rd Occurance of the is at" + example.indexOfOccurance(string,"the", nthPositionOfThe)); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | /* program to find nth occurence of a character */ import java.util.Scanner; public class CharOccur1 { public static void main(String arg[]) { Scanner scr=new Scanner(System.in); int position=-1,count=0; System.out.println("enter the string"); String str=scr.nextLine(); System.out.println("enter the nth occurence of the character"); int n=Integer.parseInt(scr.next()); int leng=str.length(); char c[]=new char[leng]; System.out.println("Enter the character to find"); char key=scr.next().charAt(0); c=str.toCharArray(); for(int i=0;i<c.length;i++) { if(c[i]==key) { count++; position=i; if(count==n) { System.out.println("Character found"); System.out.println("the position at which the" + count +" ocurrence occurs is" + position); return; } } } if(n>count) { System.out.println("Character occurs "+ count +" times"); return; } } } |