0

以下を分割したい。

name[]address[I]dob[]nationality[]occupation[]

したがって、私の結果は次のようになります。

name[]
address[I]
dob[]
nationality[]
occupation[]

使用してみRegex.Splitましたが、これらの結果が得られません。

4

5 に答える 5

4

Regex.Split次の正規表現で使用できます。

(?<=])(?=[a-z])

これは、左側の閉じ角括弧と右側の文字の間で分割されます。これは、ルックアラウンド アサーションを使用して行われます。それらは一致の文字を消費しないので、この星座では文字間で一致させるのに非常に便利です.

基本的には、私が書いたことを正確に意味します:は、文字が続く文字列 (両方ともゼロ幅、つまり文字(?<=])) のポイントに一致しますが、文字列内の右角かっこが前にあるポイントに一致します。入力データが質問で提供したものと異なる場合は、少し調整できます。(?=[a-z])

を使用して、読みやすさを犠牲にして、少し単純化することもできます(?<=])\b。しかし、通常、これは本当に醜いものであることに\b結びついているので、私はそれに対してアドバイスします. \wこれはほぼ同じように機能しますが、完全ではありません。\bこのコンテキストでは、10 進数やアンダースコアなど、より多くのものに相当し(?=[\w])、一致するためです。\w

クイック PowerShell テスト (下に .NET があるため、同じ正規表現の実装を使用します):

PS> 'name[]address[I]dob[]nationality[]occupation[]' -split '(?<=])(?=[a-z])'
name[]
address[I]
dob[]
nationality[]
occupation[]

完全を期すために、別のオプションもあります。保持したいトークン間で文字列を分割するか、保持したいトークンのすべての一致を収集することができます。後者の場合、次のような必要なものに一致するパターンが必要になります。

[a-z]+\[[^\]]*]

またはデニスが答えとして与えたもの\w(私は、それらには有用な用途がないと主張しているため、迅速で汚いハッキングやゴルフを\b除いて避ける傾向があります)。でそれを使用できますRegex.Matches

一般に、どちらのアプローチも問題なく機能しますが、分割パターンと一致パターンのどちらが理解しやすいかによって異なります。そして、オブジェクトRegex.Matchesを取得Matchするので、実際にはstring[]それが必要な場合に終わらないので、それも必要.Select(m => m.Value)になります。

この場合、どちらの正規表現も、その機能を説明するコメントなしでそのままにしておくべきではないと思います。私はそれらを問​​題なく読むことができますが、多くの開発者は正規表現に少し不安を感じており、特にルックアラウンドなどのより高度な概念については説明が必要な場合がよくあります。

于 2013-01-18T11:48:29.373 に答える
1
text.Split(new Char[] { ']' }, StringSplitOptions.RemoveEmptyEntries).Select(s => s + "]").ToArray();
于 2013-01-18T11:56:02.193 に答える
0

次の正規表現パターンを使用します。

\w*\[\w*\]
于 2013-01-18T11:54:19.623 に答える
0

正規表現は問題ないはずです。また、次のように、string.IndexOf を使用して左角括弧と右角括弧をキャッチすることも検討できます。

IEnumerable<string> Results(string input)
{
    int currentIndex = -1;
    while (true)
    {
        currentIndex++;
        int openingBracketIndex = input.IndexOf("[", currentIndex);
        int closingBracketIndex = input.IndexOf("]", currentIndex);

        if (openingBracketIndex == -1 || closingBracketIndex == -1)
            yield break;

        yield return input.Substring(currentIndex, closingBracketIndex - currentIndex + 1);
        currentIndex = closingBracketIndex;     
    }
}
于 2013-01-18T11:55:20.697 に答える
0
string inputString = "name[]address[I]dob[]nationality[]occupation[]";    
var result = Regex.Matches(inputString, @".*?\[I?\]").Cast<Match>().Select(m => m.Groups[0].Value).ToArray();
于 2013-01-18T11:58:37.980 に答える