Podobnie jak w przypadku postawionego tutaj pytania , szukam rozwiązania w Javie.
Czyli jak znaleźć indeks n-tego wystąpienia znaku / ciągu z ciągu?
Przykład: „ / folder1 / folder2 / folder3 / ”. W tym przypadku, jeśli proszę o trzecie wystąpienie ukośnika (/), pojawia się on przed folder3 i oczekuję zwrócenia tej pozycji indeksu. Moim rzeczywistym zamiarem jest wyciągnięcie go z n-tego wystąpienia postaci.
Czy jest jakaś wygodna / gotowa do użycia metoda dostępna w Java API, czy też musimy samodzielnie napisać małą logikę, aby to rozwiązać?
Również,
- Szybko sprawdziłem, czy jakakolwiek metoda jest obsługiwana w tym celu w StringUtils Apache Commons Lang , ale nie znalazłem żadnej.
- Czy wyrażenia regularne mogą w tym pomóc?
Odpowiedzi:
Jeśli twój projekt już zależy od Apache Commons, możesz użyć
StringUtils.ordinalIndexOf
, w przeciwnym razie, oto implementacja: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; }
Ten post został przepisany jako artykuł tutaj .
źródło
lastIndexOf
.Uważam, że najłatwiejszym rozwiązaniem do znalezienia N-tego wystąpienia ciągu jest użycie metody StringUtils.ordinalIndexOf () z Apache Commons.
Przykład:
StringUtils.ordinalIndexOf("aabaabaa", "b", 2) == 5
źródło
Występują dwie proste opcje:
charAt()
wielokrotnieindexOf()
wielokrotnieNa przykład:
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; }
Może to nie działać tak dobrze, jak
indexOf
wielokrotne używanie , ale prawdopodobnie łatwiej jest to naprawić.źródło
Możesz spróbować czegoś takiego:
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; } }
Zauważ, że zrobiłem kilka założeń w wyrażeniu regularnym:
Zgodnie z prośbą w komentarzu spróbuję wyjaśnić wyrażenie regularne:
(/[^/]*){2}/([^/]*)
/[^/]*
jest a,/
po którym następuje[^/]*
(dowolna liczba znaków, które nie są a/
),(/[^/]*)
grupuje poprzednie wyrażenie w jedną całość. To jest1
pierwsza grupa wyrażenia,(/[^/]*){2}
oznacza, że grupa musi dokładnie pasować do siebie{2}
,[^/]*
to znowu dowolna liczba znaków, które nie są/
,([^/]*)
grupuje poprzednie wyrażenie w jedną całość. To jest2
druga grupa wyrażenia.W ten sposób musisz tylko pobrać podciąg pasujący do drugiej grupy:
return m.group(2);
Zdjęcie dzięki uprzejmości Debuggex
źródło
Dokonałem kilku zmian w odpowiedzi aioobe i otrzymałem n-tą ostatnią wersję indeksu i naprawiłem niektóre problemy NPE. Zobacz kod poniżej:
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; }
źródło
null
jako argument. Jest to najczęstsze zachowanie w bibliotece standardowej.([.^/]*/){2}[^/]*(/)
Dopasuj cokolwiek, po którym następuje / dwa razy, a następnie ponownie. Trzeci jest tym, którego chcesz
Stan dopasowania może być użyty do określenia, gdzie jest ostatnie /
źródło
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; }
źródło
Obecnie JEST wsparcie dla StringUtils Apache Commons Lang ,
To jest prymityw:
int org.apache.commons.lang.StringUtils.ordinalIndexOf(CharSequence str, CharSequence searchStr, int ordinal)
dla swojego problemu możesz zakodować:
StringUtils.ordinalIndexOf(uri, "/", 3)
Możesz również znaleźć ostatnie n-te wystąpienie znaku w ciągu za pomocą metody lastOrdinalIndexOf .
źródło
Być może możesz to osiągnąć również za pomocą metody String.split (..).
String str = ""; String[] tokens = str.split("/") return tokens[nthIndex] == null
źródło
Inne podejście:
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); }
źródło
Ta odpowiedź jest ulepszeniem odpowiedzi @aioobe. Naprawiono dwa błędy w tej odpowiedzi.
1. n = 0 powinno zwrócić -1.
2. n-te wystąpienie zwróciło -1, ale zadziałało przy n-1-tym wystąpieniu.
Spróbuj tego !
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; }
źródło
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; } } }
źródło
Moje rozwiązanie:
/** * 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; }
źródło
/* 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; } } }
źródło
Kod zwraca podciąg pozycji n-tego wystąpienia, czyli szerokość pola. Przykład. jeśli ciąg „Stack overflow in low melow” jest ciągiem do wyszukania w drugim wystąpieniu tokena „low”, zgodzisz się ze mną, że jest to drugie wystąpienie w podciągu „18 i 21” . indexOfOccurance ("Przepełnienie stosu w niskiej temperaturze", low, 2) zwraca 18 i 21 w ciągu.
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)); } }
źródło
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; }
źródło
// scala
// rzuca -1, jeśli wartość nie jest obecna po raz n-ty, nawet jeśli jest obecna do n-1 raz. // indeks rzutu, jeśli wartość jest obecna n-ty raz
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
źródło