与发布here的问题类似,正在寻找 用于Java中的解决方案。
即,如何从字符串中找到第n次出现的字符/字符串的索引?
示例:“ / folder1 / folder2 / folder3 / ”。 在这种情况下,如果我要求第3次出现斜杠(/),它会出现在folder3之前,我希望返回这个索引位置。我的实际意图是从第n次出现的字符中对其进行子串。
Java API中是否有任何方便/现成的方法,或者我们是否需要自己编写一个小逻辑来解决这个问题?
另外,
答案 0 :(得分:121)
如果您的项目已经依赖于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;
}
此帖子已被重写为文章here。
答案 1 :(得分:55)
我认为找到第N个字符串的最简单的解决方案是使用Apache Commons的StringUtils.ordinalIndexOf()。
示例:
StringUtils.ordinalIndexOf("aabaabaa", "b", 2) == 5
答案 2 :(得分:27)
出现两个简单的选项:
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
一样好,但可能更容易做对。
答案 3 :(得分:14)
您可以尝试这样的事情:
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;
}
}
请注意,我在正则表达式中做了一些假设:
根据评论中的要求,我会尝试解释正则表达式:(/[^/]*){2}/([^/]*)
/[^/]*
是/
后跟[^/]*
(任意数量的字符不是/
),(/[^/]*)
将前一个表达式分组到一个实体中。这是表达式的1
st组,(/[^/]*){2}
表示该群组必须与{2}
次匹配,[^/]*
也是任意数量的不是/
,([^/]*)
将previos表达式分组到一个实体中。这是表达式的2
组。这样您只需获取与第二组匹配的子字符串:return m.group(2);
图片由Debuggex
提供答案 4 :(得分:8)
我对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;
}
答案 5 :(得分:5)
答案 6 :(得分:3)
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;
}
答案 7 :(得分:3)
现在支持Apache Commons Lang的StringUtils,
这是原始的:
int org.apache.commons.lang.StringUtils.ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal)
对于您的问题,您可以编写以下代码:StringUtils.ordinalIndexOf(uri, "/", 3)
您还可以使用lastOrdinalIndexOf方法在字符串中找到字符的最后第n次出现。
答案 8 :(得分:2)
另一种方法:
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);
}
答案 9 :(得分:2)
这个答案改进了@aioobe的回答。答案中的两个错误是固定的 1. n = 0应返回-1 2. nth occurence返回-1,但它在n-1次出现时起作用。
试试这个!
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;
}
答案 10 :(得分:1)
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;
}
}
}
答案 11 :(得分:1)
也许你可以通过String.split(..)方法实现这一点。
String str = "";
String[] tokens = str.split("/")
return tokens[nthIndex] == null
答案 12 :(得分:0)
我的解决方案:
/**
* 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;
}
答案 13 :(得分:0)
代码返回第n个出现位置substring又称字段宽度。例。如果字符串“Stack lowlow in low melow”是搜索第二出现令牌“low”的字符串,你会同意我第二次出现在子串“18和21”。 indexOfOccurance(“低溢出的堆栈溢出”,低,2)在字符串中返回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));
}
}
答案 14 :(得分: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;
}
}
}
答案 15 :(得分:0)
public static int findNthOccurrence(String phrase, String str, int n)
{
int val = 0, loc = -1;
for(int i = 0; i <= phrase.length()-str.length() && val < n; i++)
{
if(str.equals(phrase.substring(i,i+str.length())))
{
val++;
loc = i;
}
}
if(val == n)
return loc;
else
return -1;
}
答案 16 :(得分:0)
// scala
//如果该值第n次不存在,则抛出-1,即使该值直到第n-1次也存在。 //如果第n次出现该值,则抛出该索引
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
答案 17 :(得分:0)
这是从它们的 StringUtils 库中分离出来的确切 Apache Commons 实现(这样您就可以复制粘贴这个,而不必仅为一个函数添加库的依赖项):< /p>
/**
* <p>Finds the n-th index within a String, handling {@code null}.
* This method uses {@link String#indexOf(String)} if possible.</p>
* <p>Note that matches may overlap<p>
*
* <p>A {@code null} CharSequence will return {@code -1}.</p>
*
* @param str the CharSequence to check, may be null
* @param searchStr the CharSequence to find, may be null
* @param ordinal the n-th {@code searchStr} to find, overlapping matches are allowed.
* @param lastIndex true if lastOrdinalIndexOf() otherwise false if ordinalIndexOf()
* @return the n-th index of the search CharSequence,
* {@code -1} if no match or {@code null} string input
*/
private static int ordinalIndexOf(final String str, final String searchStr, final int ordinal, final boolean lastIndex) {
if (str == null || searchStr == null || ordinal <= 0) {
return -1;
}
if (searchStr.length() == 0) {
return lastIndex ? str.length() : 0;
}
int found = 0;
// set the initial index beyond the end of the string
// this is to allow for the initial index decrement/increment
int index = lastIndex ? str.length() : -1;
do {
if (lastIndex) {
index = str.lastIndexOf(searchStr, index - 1); // step backwards thru string
} else {
index = str.indexOf(searchStr, index + 1); // step forwards through string
}
if (index < 0) {
return index;
}
found++;
} while (found < ordinal);
return index;
}
答案 18 :(得分:0)
看起来你想要子串的字符串是一个文件路径。你不能只用 /
分割然后从兴趣点开始使用数组条目吗?例如,
String folders = "/folder1/folder2/folder3/".split('/');
StringBuilder subStringed = new StringBuilder('/');
for (int i = 2; i < folders.length; i++) {
subStringed.append(folders[i]).append('/').;
}
System.out.println(subStringed.toString());
答案 19 :(得分:0)
static int nthIndexOfChar(String str, int n, char ch) {
int count = 0;
for (int i = 0; i < str.length(); i++)
if (str.charAt(i) == ch)
if (++count == n)
return i;
return -1;
}