Bagaimana cara mengekstrak teks yang terletak di antara tanda kurung (kurung bundar)?

224

Saya memiliki string User name (sales)dan saya ingin mengekstrak teks di antara tanda kurung, bagaimana saya melakukan ini?

Saya curiga sub-string tetapi saya tidak tahu cara membaca sampai braket penutup, panjang teks akan bervariasi.

Gotqn
sumber
2
Tunjukkan pada kami apa yang telah Anda coba. Sudahkah Anda melihat menggunakan ekspresi reguler?
George Stocker

Jawaban:

445

Jika Anda ingin menjauh dari ekspresi reguler, cara paling sederhana yang dapat saya pikirkan adalah:

string input = "User name (sales)";
string output = input.Split('(', ')')[1];
Jelly Ama
sumber
91
Jujur, ini seharusnya dipilih sebagai jawabannya.
Pat Lindley
1
Bukankah itu akan dikontrak lebih lanjut menjadi input. Plit ("()". ToCharArray ()) [1]
prabhakaran
14
dan jika Anda ingin menggunakan logika yang sama untuk memilih beberapa:var input = "(fdw) User name (sales) safdsdf (again?)"; var output = input.Split('(', ')').Where((item, index) => index % 2 != 0).ToList();
WtFudgE
1
berhati-hatilah karena ekstrak solusi ini salesjuga dari string input yang mengandung )sales(, (sales(dll.
Stefano Spinucci
435

Cara yang sangat sederhana untuk melakukannya adalah dengan menggunakan ekspresi reguler:

Regex.Match("User name (sales)", @"\(([^)]*)\)").Groups[1].Value

Sebagai tanggapan terhadap komentar (sangat lucu), inilah Regex yang sama dengan beberapa penjelasan:

\(             # Escaped parenthesis, means "starts with a '(' character"
    (          # Parentheses in a regex mean "put (capture) the stuff 
               #     in between into the Groups array" 
       [^)]    # Any character that is not a ')' character
       *       # Zero or more occurrences of the aforementioned "non ')' char"
    )          # Close the capturing group
\)             # "Ends with a ')' character"
Diadistis
sumber
504
Saya suka ketika orang mengatakan "cara sederhana adalah dengan menggunakan ekspresi reguler" dan kemudian menawarkan jumlah yang setara dengan deretan hieroglif yang tidak dapat diuraikan (terutama menyenangkan ketika orang yang berbeda menyarankan regex dan masing-masing muncul dengan serangkaian hieroglif yang berbeda untuk masalah yang sama) ). :)
Deltics
47
Hampir tidak ada jawaban yang cukup pada tumpukan yang benar-benar menjelaskan apa yang terjadi. Terima kasih atas penjelasannya.
Sandy Gifford
Jika Anda menggunakan '@' di awal saya pikir Anda tidak perlu melarikan diri tanda kurung?
peringkat 1
10
@ rank1 Anda harus melarikan diri dari kurung. Apa yang ditawarkan @ di sini adalah Anda tidak perlu melarikan diri dari garis miring terbalik. Jadi tanpa @ itu akan seperti "\\ (([^)] *) \\)".
Diadistis
Ini tidak menangani grup bersarang dengan baik. Diubah menjadivar filterRegex = new Regex(Regex.Escape("(") + "([^()]*)" + Regex.Escape(")"));
Jan Van der Haegen
91

Dengan asumsi bahwa Anda hanya memiliki sepasang kurung.

string s = "User name (sales)";
int start = s.IndexOf("(") + 1;
int end = s.IndexOf(")", start);
string result = s.Substring(start, end - start);
Ross Goddard
sumber
7
mulai +1 di substring lebih benar jika Anda ingin "penjualan" daripada (penjualan)
Joze
1
apa yang akan nama happend s = "Pengguna) (Penjualan)"?
dotnetstep
@dnetnetep Anda benar seharusnya int end = s.IndexOf(")", start);. Saya sudah mengantri hasil edit ...
ChrisD
1
"(" .Length; lebih baik daripada +1. Mengirim suntingan. Juga menambahkan fungsi.
Ave
24

Gunakan fungsi ini:

public string GetSubstringByString(string a, string b, string c)
    {
        return c.Substring((c.IndexOf(a) + a.Length), (c.IndexOf(b) - c.IndexOf(a) - a.Length));
    }

dan di sini adalah penggunaannya:

GetSubstringByString("(", ")", "User name (sales)")

dan hasilnya adalah:

sales
artfulhacker
sumber
16

Ekspresi reguler mungkin menjadi alat terbaik di sini. Jika Anda tidak terbiasa dengan mereka, saya sarankan Anda menginstal Expresso - alat regex kecil yang hebat.

Sesuatu seperti:

Regex regex = new Regex("\\((?<TextInsideBrackets>\\w+)\\)");
string incomingValue = "Username (sales)";
string insideBrackets = null;
Match match = regex.Match(incomingValue);
if(match.Success)
{
    insideBrackets = match.Groups["TextInsideBrackets"].Value;
}
Jennifer
sumber
14
string input = "User name (sales)";

string output = input.Substring(input.IndexOf('(') + 1, input.IndexOf(')') - input.IndexOf('(') - 1);
Nick Allen
sumber
1
Tentu saja Anda hanya perlu menghitung lokasi braket pertama satu kali.
Martin Brown
Dalam kasus di mana Anda memiliki kurung dalam misalnya input = "User name (sales(1))Anda mungkin ingin menggunakan input.LastIndexOf(')')yang akan bekerja jika ada kurung dalam atau tidak.
Ben
13

Regex mungkin? Saya pikir ini akan berhasil ...

\(([a-z]+?)\)
menggigil42
sumber
7
using System;
using System.Text.RegularExpressions;

private IEnumerable<string> GetSubStrings(string input, string start, string end)
{
    Regex r = new Regex(Regex.Escape(start) +`"(.*?)"`  + Regex.Escape(end));
    MatchCollection matches = r.Matches(input);
    foreach (Match match in matches)
    yield return match.Groups[1].Value;
}
Bilal Mrad
sumber
4

Gunakan Ekspresi Reguler:

string test = "(test)"; 
string word = Regex.Match(test, @"\((\w+)\)").Groups[1].Value;
Console.WriteLine(word);
Will Dean
sumber
4
int start = input.IndexOf("(") + 1;
int length = input.IndexOf(")") - start;
output = input.Substring(start, length);
Gustavo Baiocchi Costa
sumber
2
input.Remove(input.IndexOf(')')).Substring(input.IndexOf('(') + 1);
Rockcoder
sumber
2

The regexMetode unggul Saya pikir, tetapi jika Anda ingin menggunakan rendah hatisubstring

string input= "my name is (Jayne C)";
int start = input.IndexOf("(");
int stop = input.IndexOf(")");
string output = input.Substring(start+1, stop - start - 1);

atau

string input = "my name is (Jayne C)";
string output  = input.Substring(input.IndexOf("(") +1, input.IndexOf(")")- input.IndexOf("(")- 1);
meskipun
sumber
1

Berikut adalah fungsi yang dapat dibaca untuk tujuan umum yang menghindari penggunaan regex:

// Returns the text between 'start' and 'end'.
string ExtractBetween(string text, string start, string end)
{
  int iStart = text.IndexOf(start);
  iStart = (iStart == -1) ? 0 : iStart + start.Length;
  int iEnd = text.LastIndexOf(end);
  if(iEnd == -1)
  {
    iEnd = text.Length;
  }
  int len = iEnd - iStart;

  return text.Substring(iStart, len);
}

Untuk menyebutnya dalam contoh khusus Anda, Anda dapat melakukan:

string result = ExtractBetween("User name (sales)", "(", ")");
ChaimG
sumber
1

Saya menemukan bahwa ekspresi reguler sangat berguna tetapi sangat sulit untuk ditulis. Jadi, saya melakukan riset dan menemukan alat ini yang membuat penulisan mereka jadi mudah.

Jangan menghindar dari mereka karena sintaksinya sulit untuk dipecahkan. Mereka bisa sangat kuat.

katyholb
sumber
2
Selamat datang di SO! Ini saran yang bagus, tetapi seharusnya tidak diposting sebagai jawaban. Nasihat umum seperti ini harus diposting sebagai komentar, jika ada. Jawaban harus mengatasi masalah khusus si penanya. Saya tahu Anda belum memiliki poin reputasi yang cukup untuk mengirim komentar, tetapi inilah alasan mengapa ambang batas rep ada. Ketika Anda sudah ada sedikit lebih lama, Anda akan melihat bahwa orang selalu merekomendasikan alat seperti Rubular (dalam komentar, tentu saja). Dengan kata lain, saran ini mungkin bermanfaat, tetapi tidak mendesak.
Alan Moore
0

Saya menemukan ini ketika saya sedang mencari solusi untuk implementasi yang sangat mirip.

Ini cuplikan dari kode saya yang sebenarnya. Mulai substring dari char pertama (indeks 0).

 string separator = "\n";     //line terminator

 string output;
 string input= "HowAreYou?\nLets go there!";

 output = input.Substring(0, input.IndexOf(separator)); 
nikk
sumber
Ini tidak menjawab apa yang diminta OP.
dicemaster
0

Kode ini lebih cepat daripada kebanyakan solusi di sini (jika tidak semua), dikemas sebagai metode ekstensi String , ini tidak mendukung penyatuan rekursif:

public static string GetNestedString(this string str, char start, char end)
{
    int s = -1;
    int i = -1;
    while (++i < str.Length)
        if (str[i] == start)
        {
            s = i;
            break;
        }
    int e = -1;
    while(++i < str.Length)
        if (str[i] == end)
        {
            e = i;
            break;
        }
    if (e > s)
        return str.Substring(s + 1, e - s - 1);
    return null;
}

Yang ini sedikit lebih lama dan lebih lambat, tetapi ia menangani sarang rekursif dengan lebih baik:

public static string GetNestedString(this string str, char start, char end)
{
    int s = -1;
    int i = -1;
    while (++i < str.Length)
        if (str[i] == start)
        {
            s = i;
            break;
        }
    int e = -1;
    int depth = 0;
    while (++i < str.Length)
        if (str[i] == end)
        {
            e = i;
            if (depth == 0)
                break;
            else
                --depth;
        }
        else if (str[i] == start)
            ++depth;
    if (e > s)
        return str.Substring(s + 1, e - s - 1);
    return null;
}
watbywbarif
sumber