İki karakter arasında bir dizi nasıl alınır?


93

Bir ipim var

String s = "test string (67)";

(Ve) arasındaki dize olan 67 numarayı almak istiyorum.

Biri bana bunu nasıl yapacağımı söyleyebilir mi?


1
Birkaç yolu vardır - Eğer ulaşana kadar dizede karakter yineleme (ya da ilk dizinini bulmak (ve )ve ya, çoğu insan ne yapacağını, normal bir ifade kullanmak alt dize ile bunu.
Andreas Dolk

Yanıtlar:


103

Muhtemelen gerçekten düzgün bir RegExp var, ama o bölgede çaylak değilim, bu yüzden onun yerine ...

String s = "test string (67)";

s = s.substring(s.indexOf("(") + 1);
s = s.substring(0, s.indexOf(")"));

System.out.println(s);

4
Normal ifade ayrıştırmanın tuhaflıklarından geçmeden, bunun gerekli dizeyi çıkarmanın en iyi yolu olduğunu düşünüyorum.
verisimilitude

3
regex çok daha güçlüdür ve daha fazla durumda kullanılabilir, ancak basit olması için bu işe
yarar

2
Cidden, bu neden olumsuz bir oy alsın? İşe yaramıyor mu? Operasyon sorusuna cevap vermiyor mu?
MadProgrammer

eğer birden fazla değere 'this is an example of <how><i have it>'
sahipsem,

@Vignesh Normal bir ifade kullanın
MadProgrammer

74

IndexOf işlemini yapmanızı gerektirmeyen bu soruna çok faydalı bir çözüm Apache Commons kitaplıklarını kullanmaktır.

 StringUtils.substringBetween(s, "(", ")");

Bu yöntem, indexOf kapanış dizesini arayarak kolay olmayacak birden çok kapanış dizesi olsa bile işlemenizi sağlar.

Bu kitaplığı buradan indirebilirsiniz: https://mvnrepository.com/artifact/org.apache.commons/commons-lang3/3.4


7
Orada da substringsBetween(...)ben aradığı şeyi olan birden fazla sonuç bekliyorsanız. Teşekkürler
cahen


72

Böyle dene

String s="test string(67)";
String requiredString = s.substring(s.indexOf("(") + 1, s.indexOf(")"));

Yöntemin alt dize için imzası:

s.substring(int start, int end);

30

Normal ifade kullanarak:

 String s = "test string (67)";
 Pattern p = Pattern.compile("\\(.*?\\)");
 Matcher m = p.matcher(s);
 if(m.find())
    System.out.println(m.group().subSequence(1, m.group().length()-1)); 

2
Bunu ". *?" Kullanarak açgözlü olmayan bir eşleştirme yapmanız gerektiğini düşünüyorum. yerine. Aksi takdirde, dizge "test dizisi (67) ve (68) gibi
yatıştırıcıysa

18

Java, Normal İfadeleri destekler , ancak eşleşmeleri çıkarmak için bunları gerçekten kullanmak istiyorsanız, bunlar biraz külfetli olabilir. Örneğinizde istediğiniz dizgeye ulaşmanın en kolay yolu, Stringsınıfın replaceAllyönteminde Regular Expression desteğini kullanmaktır :

String x = "test string (67)".replaceAll(".*\\(|\\).*", "");
// x is now the String "67"

Bu, birincisi dahil olmak üzere her şeyi ve daha sonraki her şey (için aynı şeyi siler ). Bu sadece parantez içinde kalan şeyleri bırakır.

Ancak, bunun sonucu hala a String. Bunun yerine bir tamsayı sonucu istiyorsanız, başka bir dönüştürme yapmanız gerekir:

int n = Integer.parseInt(x);
// n is now the integer 67

10

Tek bir satırda şunları öneririm:

String input = "test string (67)";
input = input.subString(input.indexOf("(")+1, input.lastIndexOf(")"));
System.out.println(input);`

7
String s = "test string (67)";

int start = 0; // '(' position in string
int end = 0; // ')' position in string
for(int i = 0; i < s.length(); i++) { 
    if(s.charAt(i) == '(') // Looking for '(' position in string
       start = i;
    else if(s.charAt(i) == ')') // Looking for ')' position in  string
       end = i;
}
String number = s.substring(start+1, end); // you take value between start and end

7

Bunu yapmak için apache ortak kitaplığının StringUtils işlevini kullanabilirsiniz.

import org.apache.commons.lang3.StringUtils;
...
String s = "test string (67)";
s = StringUtils.substringBetween(s, "(", ")");
....

7
String result = s.substring(s.indexOf("(") + 1, s.indexOf(")"));

1
Lütfen kodunuzu 4 boşluk girerek biçimlendirin. Ayrıca, .substring.indexOf`un ne yaptığından emin olmayan ziyaretçilere kodunuzun ne yaptığını açıklayarak cevabınızı biraz kısaltabilirim.
Bugs

6

test string (67)İki Dize arasında yuvalanmış String'i almanız gereken Test Dizesi .

String str = "test string (67) and (77)", open = "(", close = ")";

Bazı olası yollar listelenmiştir : Basit Genel Çözüm:

String subStr = str.substring(str.indexOf( open ) + 1, str.indexOf( close ));
System.out.format("String[%s] Parsed IntValue[%d]\n", subStr, Integer.parseInt( subStr ));

Apache Yazılım Vakfı commons.lang3.

StringUtilssınıf substringBetween()işlevi, iki Dizenin arasına yerleştirilmiş String'i alır. Yalnızca ilk eşleşme döndürülür.

String substringBetween = StringUtils.substringBetween(subStr, open, close);
System.out.println("Commons Lang3 : "+ substringBetween);

Verilen Dize'yi iki Dize arasında yuvalanmış Dize ile değiştirir. #395


Normal İfadelerle Desen: (\()(.*?)(\)).*

Nokta Maçlar (Neredeyse) Herhangi Karakter .? = .{0,1}, .* = .{0,}, .+ = .{1,}

String patternMatch = patternMatch(generateRegex(open, close), str);
System.out.println("Regular expression Value : "+ patternMatch);

Yardımcı sınıf RegexUtilsve bazı işlevlerle Düzenli İfade .
      Pattern.DOTALL: Satır sonlandırıcı dahil herhangi bir karakterle eşleşir.
      Pattern.MULTILINE: Giriş dizisinin başından ^sonuna kadar tüm Dizeyi $eşleştirir.

public static String generateRegex(String open, String close) {
    return "(" + RegexUtils.escapeQuotes(open) + ")(.*?)(" + RegexUtils.escapeQuotes(close) + ").*";
}

public static String patternMatch(String regex, CharSequence string) {
    final Pattern pattern  = Pattern.compile(regex, Pattern.DOTALL);
    final Matcher matcher = pattern .matcher(string);

    String returnGroupValue = null;
    if (matcher.find()) { // while() { Pattern.MULTILINE }
        System.out.println("Full match: " + matcher.group(0));
        System.out.format("Character Index [Start:End]«[%d:%d]\n",matcher.start(),matcher.end());
        for (int i = 1; i <= matcher.groupCount(); i++) {
            System.out.println("Group " + i + ": " + matcher.group(i));
            if( i == 2 ) returnGroupValue = matcher.group( 2 );
        }
    }
    return returnGroupValue;
}

StringUtils çok kullanışlı
TuGordoBello

5
public String getStringBetweenTwoChars(String input, String startChar, String endChar) {
    try {
        int start = input.indexOf(startChar);
        if (start != -1) {
            int end = input.indexOf(endChar, start + startChar.length());
            if (end != -1) {
                return input.substring(start + startChar.length(), end);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return input; // return null; || return "" ;
}

Kullanım:

String input = "test string (67)";
String startChar = "(";
String endChar   = ")";
String output = getStringBetweenTwoChars(input, startChar, endChar);
System.out.println(output);
// Output: "67"

4

Kullanım Pattern and Matcher

public class Chk {

    public static void main(String[] args) {

        String s = "test string (67)";
        ArrayList<String> arL = new ArrayList<String>();
        ArrayList<String> inL = new ArrayList<String>();

        Pattern pat = Pattern.compile("\\(\\w+\\)");
        Matcher mat = pat.matcher(s);

        while (mat.find()) {

            arL.add(mat.group());
            System.out.println(mat.group());

        }

        for (String sx : arL) {

            Pattern p = Pattern.compile("(\\w+)");
            Matcher m = p.matcher(sx);

            while (m.find()) {

                inL.add(m.group());
                System.out.println(m.group());
            }
        }

        System.out.println(inL);

    }

}

2
Değişken isimlerini konuşmak, yöntemi daha kolay hale getirebilir.
Zon

3

Bölme yöntemini kullanmanın başka bir yolu

public static void main(String[] args) {


    String s = "test string (67)";
    String[] ss;
    ss= s.split("\\(");
    ss = ss[1].split("\\)");

    System.out.println(ss[0]);
}

3

Bunu Regex ve Pattern / Matcher sınıflarıyla yapmanın en az genel yolu:

String text = "test string (67)";

String START = "\\(";  // A literal "(" character in regex
String END   = "\\)";  // A literal ")" character in regex

// Captures the word(s) between the above two character(s)
String pattern = START + "(\w+)" + END;

Pattern pattern = Pattern.compile(pattern);
Matcher matcher = pattern.matcher(text);

while(matcher.find()) {
    System.out.println(matcher.group()
        .replace(START, "").replace(END, ""));
}

Bu, metni iki karakter dizisi arasında almak istediğiniz daha karmaşık normal ifade problemlerinde yardımcı olabilir.


2

Bunu yapmanın "genel" yolu, dizeyi baştan ayrıştırmak, ilk parantezin önündeki tüm karakterleri atmak, ilk parantezden sonraki karakterleri kaydetmek ve ikinci parantezden sonraki karakterleri atmaktır.

Eminim bir normal ifade kitaplığı veya yapacak bir şey vardır.


Java, normal ifadeleri destekler. Regexp4j kitaplığına gerek yok;)
Andreas Dolk

2
String s = "test string (67)";

System.out.println(s.substring(s.indexOf("(")+1,s.indexOf(")")));

2

Diğer olası çözüm kullanmaktır lastIndexOf karakter veya String'i geriye doğru arayacağı yerde .

Benim senaryomda aşağıdakiler Stringvardı ve çıkarmak zorunda kaldım<<UserName>>

1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc

Yani, indexOfve StringUtils.substringBetweenonlar başından karakteri arayan başlamadan gibi yararlı değildi.

Bu yüzden kullandım lastIndexOf

String str = "1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc";
String userName = str.substring(str.lastIndexOf("_") + 1, str.lastIndexOf("."));

Ve bana veriyor

<<UserName>>

1

Bunun gibi bir şey:

public static String innerSubString(String txt, char prefix, char suffix) {

    if(txt != null && txt.length() > 1) {

        int start = 0, end = 0;
        char token;
        for(int i = 0; i < txt.length(); i++) {
            token = txt.charAt(i);
            if(token == prefix)
                start = i;
            else if(token == suffix)
                end = i;
        }

        if(start + 1 < end)
            return txt.substring(start+1, end);

    }

    return null;
}

1

Bu basit bir kullanım \D+normal ifadesi ve yapılan iştir.
Bu, rakamlar hariç tüm karakterleri seçer, karmaşıklaştırmaya gerek yoktur

/\D+/

1

Normal ifadeyle eşleşmezse orijinal dizeyi döndürür

var iAm67 = "test string (67)".replaceFirst("test string \\((.*)\\)", "$1");

koda eşleşme ekle

String str = "test string (67)";
String regx = "test string \\((.*)\\)";
if (str.matches(regx)) {
    var iAm67 = str.replaceFirst(regx, "$1");
}

---DÜZENLE---

i kullanmak https://www.freeformatter.com/java-regex-tester.html#ad-outputregex'i test etmek .

eklemenin daha iyi olduğu ortaya çıktı? daha az eşleşme için * sonra. bunun gibi bir şey:

String str = "test string (67)(69)";
String regx1 = "test string \\((.*)\\).*";
String regx2 = "test string \\((.*?)\\).*";
String ans1 = str.replaceFirst(regx1, "$1");
String ans2 = str.replaceFirst(regx2, "$1");
System.out.println("ans1:"+ans1+"\nans2:"+ans2); 
// ans1:67)(69
// ans2:67
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.