括弧(丸括弧)の間にあるテキストを抽出するにはどうすればよいですか?


224

文字列がUser name (sales)あり、括弧内のテキストを抽出したいのですが、どうすればよいですか?

私は部分文字列を疑っていますが、閉じ括弧まで読む方法を理解することができません。テキストの長さが異なります。


2
何を試したかを見せてください。正規表現の使用を見てきましたか?
ジョージストッカー

回答:


445

正規表現を避けたい場合、私が考えられる最も簡単な方法は次のとおりです。

string input = "User name (sales)";
string output = input.Split('(', ')')[1];

91
正直なところ、これは答えとして選択されるべきでした。
Pat Lindley 2013年

1
input.Split( "()"。ToCharArray())[1]
prabhakaran

14
同じロジックを使用して複数を選択する場合:var input = "(fdw) User name (sales) safdsdf (again?)"; var output = input.Split('(', ')').Where((item, index) => index % 2 != 0).ToList();
WtFudgE

1
このソリューションは、などsalesを含む入力文字列からも抽出されることに注意してください)sales((sales(
Stefano Spinucci '15

435

これを行う非常に簡単な方法は、正規表現を使用することです。

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

(非常に面白い)コメントへの応答として、いくつかの説明付きの同じ正規表現を以下に示します。

\(             # 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"

504
人々が「単純な方法は正規表現を使用することである」と言ってそれから解読不可能な象形文字の列に相当するものを提供するときに私はそれが大好きです)。:)
Deltics

47
何が起こっているのかを実際に説明する十分な回答がスタックにほとんどありません。 素晴らしい説明ありがとうございます
Sandy Gifford 2013年

最初に「@」を使用している場合、かっこをエスケープする必要はないと思いますか?
ランク1 2013年

10
@ rank1括弧をエスケープする必要があります。ここで@が提供するのは、バックスラッシュをエスケープする必要がないことです。したがって、@がないと、「\\(([^)] *)\\)」のようになります。
Diadistis 2013年

ただし、これはネストされたグループをうまく処理しません。変更var filterRegex = new Regex(Regex.Escape("(") + "([^()]*)" + Regex.Escape(")"));
Jan Van der Haegen

91

括弧が1組しかないと仮定します。

string s = "User name (sales)";
int start = s.IndexOf("(") + 1;
int end = s.IndexOf(")", start);
string result = s.Substring(start, end - start);

7
(sales)の代わりに "sales"が必要な場合、サブストリングのstart + 1がより正確です
Joze

1
s = "User)name(Sales)"はどうなりますか?
dotnetstep 2013年

あなたが正しい@dotnetstepである必要がありますint end = s.IndexOf(")", start);。私は編集をキューに入れました...
ChrisD 2014

1
「(」.LENGTHは、1よりも優れて編集を送信また、機能を追加しました。。。
アベニュー

24

この関数を使用します。

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

そしてここに使用法があります:

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

出力は次のようになります。

sales

16

正規表現は、ここでの最良のツールかもしれません。それらに慣れていない場合は、Expressoをインストールすることをお勧めします-優れた小さな正規表現ツールです。

何かのようなもの:

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;
}

14
string input = "User name (sales)";

string output = input.Substring(input.IndexOf('(') + 1, input.IndexOf(')') - input.IndexOf('(') - 1);

1
もちろん、最初のブラケットの位置を一度だけ計算する必要があります。
マーティンブラウン、

あなたが内側の括弧を持っている場合、例えば、内側の括弧があるかどうかにかかわらず機能input = "User name (sales(1))するinput.LastIndexOf(')')ものを使いたいかもしれません。
Ben

13

多分正規表現?これはうまくいくと思います...

\(([a-z]+?)\)

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;
}

4

正規表現を使用する:

string test = "(test)"; 
string word = Regex.Match(test, @"\((\w+)\)").Groups[1].Value;
Console.WriteLine(word);



2

regexこの方法は、私が考える優れているが、あなたは謙虚を使用したい場合substring

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

または

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

1

次に、正規表現の使用を回避する汎用の読み取り可能な関数を示します。

// 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);
}

あなたの特定の例でそれを呼び出すには、次のことができます:

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

1

正規表現は非常に便利ですが、書くのが非常に難しいことがわかりました。それで、私はいくつかの研究をして、それらをとても簡単に書くことができるこのツールを見つけました。

構文を理解するのは難しいので、それらを避けないでください。彼らはとても強力なことができます。


2
SOへようこそ!これは良いアドバイスですが、回答として投稿されるべきではありませんでした。このような一般的なアドバイスは、もしあればコメントとして投稿する必要があります。答えは、質問者の特定の問題に対処する必要があります。コメントを投稿するのに十分なレピュテーションポイントがないことはわかっていますが、これが正確に担当者のしきい値が存在する理由です。あなたがもう少し長くいると、人々は常にRubularなどのツールを推奨していることがわかります(もちろん、コメントで)。つまり、このアドバイスは役立つかもしれませんが、緊急ではありません。
アランムーア

0

非常によく似た実装のソリューションを探していたときに、これに遭遇しました。

これが私の実際のコードからの抜粋です。最初の文字(インデックス0)から部分文字列を開始します。

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

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

 output = input.Substring(0, input.IndexOf(separator)); 

これは、OPが求めたものには答えません。
ダイスマスター2018

0

このコードは、すべてではないにしても、ほとんどのソリューションよりも高速で、文字列 拡張メソッドとしてパックされています。再帰的なネストはサポートされていません。

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;
}

これは少し長くて遅いですが、再帰的なネストをよりうまく処理します:

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;
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.