如何findstring中的第n个字符?
类似于这里发布的问题,我正在寻找一个Java解决scheme。
也就是说,如何从string中find第n个字符/string出现的索引?
例如: “ / folder1 / folder2 / folder3 / ”。 在这种情况下,如果我要求第三次出现斜杠(/),它会出现在folder3之前,我希望返回这个索引位置。 我的实际意图是将它从第n个字符的string中抽取出来。
在Java API中是否有任何方便/可用的方法,或者我们是否需要编写一个小逻辑来解决这个问题?
也,
- 我很快search了Apache Commons Lang的StringUtils是否支持任何方法,但是我没有find任何方法。
- 正则expression式可以在这方面帮助吗?
如果你的项目已经依赖Apache Commons,你可以使用StringUtils.ordinalIndexOf
,否则,这里有一个实现:
public static int ordinalIndexOf(String str, String substr, int n) { int pos = str.indexOf(substr); while (--n > 0 && pos != -1) pos = str.indexOf(substr, pos + 1); return pos; }
这篇文章在这里被重写为一篇文章。
我相信find第N个string的最简单的方法是使用Apache Commons中的StringUtils.ordinalIndexOf() 。
例:
StringUtils.ordinalIndexOf("aabaabaa", "b", 2) == 5
两个简单的选项发生:
- 重复使用
charAt()
- 重复使用
indexOf()
例如:
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; }
这可能不会像重复使用indexOf
一样执行,但它可能更简单得到正确的。
你可以尝试这样的事情:
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; } }
请注意,我在正则expression式中做了一些假设:
- inputpath是绝对的(即以“/”开始);
- 结果中不需要第三个“/”。
正如在评论中所要求的,我将尝试解释正则expression式: (/[^/]*){2}/([^/]*)
-
/[^/]*
是一个/
后跟[^/]*
(任何不是/
的字符数), -
(/[^/]*)
将以前的expression式分组到单个实体中。 这是expression的1
组, -
(/[^/]*){2}
表示该组必须严格匹配{2}
次, -
[^/]*
是任何不是/
的字符数, -
([^/]*)
将previosexpression式分组到单个实体中。 这是expression的第二组。
这样,你只需要得到匹配第二组的子string: return m.group(2);
图片由Debuggex提供
我对aioobe的答案做了一些修改,得到了第n个lastIndexOf版本,并修复了一些NPE问题。 见下面的代码:
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; }
([.^/]*/){2}[^/]*(/)
匹配任何后面的/两次,然后再次。 第三个是你想要的
匹配状态可以用来告诉最后一个/哪里
现在有Apache Commons Lang的StringUtils的支持 ,
这是原始的:
int org.apache.commons.lang.StringUtils.ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal)
对于你的问题,你可以编码如下: StringUtils.ordinalIndexOf(uri, "/", 3)
您还可以使用lastOrdinalIndexOf方法findstring中最后一个出现的字符。
public static int nth(String source, String pattern, int n) { int i = 0, pos = 0, tpos = 0; while (i < n) { pos = source.indexOf(pattern); if (pos > -1) { source = source.substring(pos+1); tpos += pos+1; i++; } else { return -1; } } return tpos - 1; }
这个答案改善了@aioobe的答案。 在这个答案中的两个错误是固定的。
1. n = 0应该返回-1。
2.第n次出现返回-1,但是它在第n次出现时起作用。
尝试这个 !
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; }
另一种方法:
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); }
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; } } }
/* 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; } } }
我的解决scheme
/** * Like String.indexOf, but find the n:th occurance of c * @param s string to search * @param c character to search for * @param nn: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个出现位置子string字段宽度。 例。 如果string“低层堆栈溢出”是search第二个标记“low”的string,你会同意我第二个发生在子string“18和21” 。 indexOfOccurance(“在低melow中堆栈溢出”,低,2)返回string中的18和21。
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)); } }
//在纯c ++中
int pos = 0; for ( int i = 0; i < N; ++i ) // N = nth position { pos = STRING.find( delim, pos + size_of_delim ); }