Bagaimana cara mendapatkan string antara dua karakter?

93

Aku punya tali,

String s = "test string (67)";

Saya ingin mendapatkan no 67 yang merupakan string antara (dan).

Adakah yang bisa memberi tahu saya bagaimana melakukan ini?

Roshanck
sumber
1
Ada beberapa cara - Anda dapat mengulang karakter dalam string sampai Anda mencapai (atau menemukan indeks yang pertama (dan )dan melakukannya dengan substring atau, yang akan dilakukan kebanyakan orang, menggunakan ekspresi reguler.
Andreas Dolk

Jawaban:

103

Mungkin ada RegExp yang sangat rapi, tapi saya noob di area itu, jadi sebagai gantinya ...

String s = "test string (67)";

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

System.out.println(s);
MadProgrammer
sumber
4
Tanpa melalui keanehan parsing regex, saya rasa ini adalah cara terbaik untuk mengekstrak string yang dibutuhkan.
verisimilitude
3
regex jauh lebih kuat dan dapat menangani lebih banyak kasus, tetapi untuk kesederhanaan, ini berfungsi ...
MadProgrammer
2
Sungguh, mengapa ini menarik suara yang turun? Apakah itu tidak berhasil? Apakah itu tidak menjawab pertanyaan ops?
MadProgrammer
jika saya memiliki beberapa nilai lalu bagaimana saya bisa menggunakan substring menganggap saya memiliki string seperti ini 'this is an example of <how><i have it>'dan saya perlu menemukan nilai antara '<' dan '>' ini
Vignesh
@Vignesh Gunakan ekspresi reguler
MadProgrammer
74

Solusi yang sangat berguna untuk masalah ini yang tidak mengharuskan Anda untuk melakukan indexOf adalah menggunakan pustaka Apache Commons .

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

Metode ini akan memungkinkan Anda bahkan menangani bahkan jika ada beberapa kejadian dari string penutup yang tidak akan mudah dengan mencari string penutup indexOf.

Anda dapat mengunduh perpustakaan ini dari sini: https://mvnrepository.com/artifact/org.apache.commons/commons-lang3/3.4

Pini Cheyni
sumber
7
Ada juga substringsBetween(...)jika Anda mengharapkan banyak hasil, itulah yang saya cari. Terima kasih
cahen
Tautkan dengan lebih banyak contoh- commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/…
Avisek Chakraborty
72

Cobalah seperti ini

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

Tanda tangan metode untuk substring adalah:

s.substring(int start, int end);
pengguna2656003
sumber
30

Dengan menggunakan ekspresi reguler:

 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)); 
Grisha Weintraub
sumber
2
Saya pikir Anda harus membuat pertandingan ini tidak serakah dengan menggunakan ". *?" sebagai gantinya. Sebaliknya, jika stringnya adalah sesuatu seperti "string uji (67) dan (68), ini akan mengembalikan" 67) dan (68 ".
Chthonic Project
18

Java mendukung Ekspresi Reguler , tetapi agak merepotkan jika Anda benar-benar ingin menggunakannya untuk mengekstrak persamaan. Saya pikir cara termudah untuk mendapatkan string yang Anda inginkan dalam contoh Anda adalah dengan hanya menggunakan dukungan Ekspresi Reguler dalam metode Stringkelas replaceAll:

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

Ini hanya menghapus semua yang up-to-dan-termasuk yang pertama (, dan yang sama untuk )dan semua yang sesudahnya. Ini hanya menyisakan hal-hal di antara tanda kurung.

Namun, hasil dari ini masih a String. Jika Anda menginginkan hasil integer, maka Anda perlu melakukan konversi lain:

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

Dalam satu baris, saya sarankan:

String input = "test string (67)";
input = input.subString(input.indexOf("(")+1, input.lastIndexOf(")"));
System.out.println(input);`
Hujan
sumber
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
Piotr Chojnacki
sumber
7

Anda bisa menggunakan StringUtils perpustakaan umum apache untuk melakukan ini.

import org.apache.commons.lang3.StringUtils;
...
String s = "test string (67)";
s = StringUtils.substringBetween(s, "(", ")");
....
ChaitanyaBhatt
sumber
7
String result = s.substring(s.indexOf("(") + 1, s.indexOf(")"));
techlearner
sumber
1
Harap format kode Anda dengan membuat indentasi 4 spasi. Juga saya akan memberikan jawaban Anda sedikit dengan menjelaskan apa yang kode Anda lakukan untuk mereka yang mengunjungi yang tidak yakin apa .substringdan .indexOf` tidak.
Bugs
6

Uji String test string (67)dari mana Anda perlu mendapatkan String yang bersarang di antara dua String.

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

Tercantum beberapa kemungkinan cara : Solusi Generik Sederhana:

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

Yayasan Perangkat Lunak Apache commons.lang3.

StringUtilsclass substringBetween()function mendapatkan String yang berada di antara dua String. Hanya pertandingan pertama yang dikembalikan.

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

Mengganti String yang diberikan, dengan String yang berada di antara dua String. #395


Pola dengan Ekspresi Reguler: (\()(.*?)(\)).*

The Dot Cocok (Hampir) Setiap Karakter .? = .{0,1}, .* = .{0,}, .+ = .{1,}

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

Regular-Expression dengan kelas utilitas RegexUtilsdan beberapa fungsi.
      Pattern.DOTALL: Mencocokkan karakter apa pun, termasuk terminator baris.
      Pattern.MULTILINE: Mencocokkan seluruh String dari awal ^hingga akhir $urutan input.

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;
}
Yash
sumber
StringUtils sangat berguna
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 "" ;
}

Penggunaan:

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

Menggunakan 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);

    }

}
Kumar Vivek Mitra
sumber
2
Mengucapkan nama variabel bisa membuat metode lebih ramah.
Zon
3

Cara lain melakukannya dengan menggunakan metode split

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]);
}
Jayy
sumber
3

Cara paling tidak umum yang saya temukan untuk melakukan ini dengan kelas Regex dan Pattern / Matcher:

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, ""));
}

Ini dapat membantu untuk masalah ekspresi reguler yang lebih kompleks saat Anda ingin mendapatkan teks di antara dua set karakter.

Menjadi
sumber
2

Cara "umum" untuk melakukan ini adalah dengan mengurai string dari awal, membuang semua karakter sebelum tanda kurung pertama, merekam karakter setelah tanda kurung pertama, dan membuang karakter setelah tanda kurung kedua.

Saya yakin ada perpustakaan regex atau sesuatu untuk melakukannya.

Jonathon Ashworth
sumber
Java mendukung ekspresi reguler. Tidak perlu perpustakaan regexp4j;)
Andreas Dolk
2
String s = "test string (67)";

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

Solusi lain yang mungkin adalah menggunakan di lastIndexOfmana ia akan mencari karakter atau String dari belakang.

Dalam skenario saya, saya mengikuti Stringdan saya harus mengekstraknya<<UserName>>

1QAJK-WKJSH_MyApplication_Extract_<<UserName>>.arc

Jadi, indexOfdan StringUtils.substringBetweentidak membantu karena mereka mulai mencari karakter dari awal.

Jadi, saya dulu lastIndexOf

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

Dan, itu memberi saya

<<UserName>>
Ravi
sumber
1

Sesuatu seperti ini:

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;
}
Ahmad AlMughrabi
sumber
1

Ini adalah \D+regex penggunaan sederhana dan pekerjaan selesai.
Ini pilih semua karakter kecuali angka, tidak perlu rumit

/\D+/
Pascal Tovohery
sumber
1

itu akan mengembalikan string asli jika tidak ada regex yang cocok

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

tambahkan kecocokan ke kode

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

--- EDIT ---

saya menggunakan https://www.freeformatter.com/java-regex-tester.html#ad-output untuk menguji regex.

ternyata lebih baik menambahkan? setelah * untuk kurang cocok. sesuatu seperti ini:

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
bigiCrab
sumber