如何在字符串中找到第n个字符?
与发布的问题类似here,我正在寻找 以获得Java解决方案。如何在字符串中找到第n个字符?
也就是说,如何从字符串中找到第n个字符/字符串出现的索引?
示例: “/folder1中/文件夹2/folder3/”。 在这种情况下,如果我要求第3次出现斜杠(/),它会出现在folder3之前,并且我希望返回此索引位置。我的实际意图是从第n个字符开始对它进行子串处理。
在Java API中是否有任何方便/可用的方法,或者我们是否需要自己编写一个小逻辑来解决这个问题?
此外,
- 我快速地搜索任何方法是否支持此目的,在阿帕奇共享郎的StringUtils,但我没有找到任何。
- 正则表达式在这方面可以提供帮助吗?
两个简单的选项出现:
- 使用
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
,但它可能更容易得到正确。
我相信这是一个非常酷的答案,但是如何在我的代码中使用它? – 2015-08-05 18:30:23
看看@ andcoz的回答(不同的正则表达式,但想法是一样的) – 2015-08-05 18:34:32
如果您的项目已经依赖于Apache的共享,你可以使用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。
除了“off-by-one”错误之外,@Jon Skeet的解决方案还有另一个很大的好处 - 只需稍微调整一下(反转循环) ,你也可以有“最后一次出现”。 – 2016-05-12 21:30:02
@KaranChadha,同样适用于此解决方案。只需转到['lastIndexOf'](https://docs.oracle.com/javase/7/docs/api/java/lang/String.html#lastIndexOf%28java.lang.String,%20int%29)。 – aioobe 2016-06-29 21:44:12
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;
}
你可以尝试这样的事情:
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}/([^/]*)
-
/[^/]*
是/
其次[^/]*
(即任何数目的字符不是/
), -
(/[^/]*)
groups th e先前在单个实体中的表达。这是1
第一组的表达的, -
(/[^/]*){2}
指该基团必须匹配您准确{2}
倍, -
[^/]*
再次是不属于/
, -
([^/]*)
基团在所述previos表达的任何数量的字符单一实体。这是表达式的2
第二组。
这种方式你只拿到了第2组相匹配的子字符串:return m.group(2);
图片礼貌Debuggex
另一种方法:
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);
}
我相信最简单的解决方案找到String的第N次出现是使用Apache Commons中的StringUtils.ordinalIndexOf()。
例子:
StringUtils.ordinalIndexOf("aabaabaa", "b", 2) == 5
我做了一些改动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;
}
我认为如果给出'null'作为参数,该方法抛出NPE是合理的。这是标准库中最常见的行为。 – aioobe 2015-12-10 22:54:51
/* 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;
}
}
}
//纯C++
int pos = 0;
for (int i = 0; i < N; ++i) // N = nth position
{
pos = STRING.find(delim, pos + size_of_delim);
}
如今有支撑的Apache的百科全书Lang的StringUtils,
这是原始:
int org.apache.commons.lang.StringUtils.ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal)
您的问题,您可以编写以下:StringUtils.ordinalIndexOf(uri, "/", 3)
您还可以找到与lastOrdinalIndexOf方法的字符串的字符的最后第n次出现。
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;
}
}
}
这个答案改善了@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;
}
我的解决办法:
/**
* 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个发生位置串又名字段宽度。例。如果字符串“堆栈溢出在低melow”是要搜索的字符串第二个发生令牌“低”,你会同意我第二次发生在子字符串“18和21”。 indexOfOccurance(“在低melow中堆栈溢出”,低,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));
}
}
也许你可以通过String.split(..)方法实现这一点。
String str = "";
String[] tokens = str.split("/")
return tokens[nthIndex] == null
对于您的特定示例,根据您想要对结果执行的操作,将字符串拆分为/可能会更容易,这可能会直接提供您所需的内容? – 2010-10-20 10:09:03
@Paul:这也是个好主意。 – Gnanam 2010-10-20 11:33:39