С# Regex.Match фигурные скобки - только содержимое? (исключить брекеты) - программирование
Подтвердить что ты не робот

С# Regex.Match фигурные скобки - только содержимое? (исключить брекеты)

Мне не удалось найти ответ на этот вопрос: могу ли я использовать метод Regex.Matches для возврата только содержимого элементов с фигурными фигурными скобками?

Если я использую Regex ({[^}]*}), мои MatchCollection значения включают в себя фигурные скобки. Я хочу совместить, но потом возвращать содержимое. Вот что я до сих пор:

Regex regex = new Regex(({[^}]*}), RegexOptions.IgnoreCase);
MatchCollection matches = regex.Matches("Test {Token1} {Token 2}");
// Results include braces (undesirable)
var results = matches.Cast<Match>().Select(m => m.Value).Distinct().ToList();
4b9b3361

Ответ 1

Мне всегда нравилось это явное. Таким образом, вы можете использовать "положительный lookbehind" (? < =...) и "положительный lookahead" (? =...) группы:

(?<=\{)
[^}]*
(?=\})

что означает:

  • требуется открыть фигурные скобки до
  • собирать текст (из, конечно) - как было прокомментировано, прежде чем я [^ {}] * также
  • требуется закрыть фигурный скоб после

Ответ 2

В С#, как и во многих других языках программирования, механизм regex поддерживает группы захвата, которые являются подматрицами, частями подстрок, которые соответствуют шаблону регулярного выражения, определенным в шаблоне регулярного выражения с помощью круглые скобки (например, 1([0-9])3 будет соответствовать 123 и сохранить значение 2 в буфер группы захвата 1). Доступ к захваченным текстам осуществляется через Match.Groups[n].Value, где n - это индекс группы захвата внутри шаблона.

Захват гораздо эффективнее, чем поиск. Всякий раз, когда нет необходимости в сложных условиях, группы захвата являются намного лучшими альтернативами.

См. мой тест скорости регулярного выражения, выполненный в regexhero.net:

введите описание изображения здесь

Теперь, как мы можем получить подстроку внутри фигурных скобок?

  • если внутри нет других фигурных скобок с отрицательным символьным классом: {([^{}]*)
  • если могут быть вложенные фигурные скобки: {((?>[^{}]+|{(?<c>)|}(?<-c>))*(?(c)(?!)))

В обоих случаях мы сопоставляем открытие {, а затем сопоставляем (1) любой символ, отличный от { или }, или (2) любые символы до первого парного }.

Вот пример кода:

var matches = Regex.Matches("Test {Token1} {Token 2}", @"{([^{}]*)");
var results = matches.Cast<Match>().Select(m => m.Groups[1].Value).Distinct().ToList();
Console.WriteLine(String.Join(", ", results));
matches = Regex.Matches("Test {Token1} {Token {2}}", @"{((?>[^{}]+|{(?<c>)|}(?<-c>))*(?(c)(?!)))");
results = matches.Cast<Match>().Select(m => m.Groups[1].Value).Distinct().ToList();
Console.WriteLine(String.Join(", ", results));

Результат: Token1, Token 2, Token1, Token {2}.

Обратите внимание, что RegexOptions.IgnoreCase избыточно, если у вас нет буквенных букв, которые могут иметь различный случай в шаблоне.

Ответ 3

Спасибо Милош Краевский, ничего добавить, но вот функция

private List<String> GetTokens(String str)
{
    Regex regex = new Regex(@"(?<=\{)[^}]*(?=\})", RegexOptions.IgnoreCase);
    MatchCollection matches = regex.Matches(str);

    // Results include braces (undesirable)
    return matches.Cast<Match>().Select(m => m.Value).Distinct().ToList();
}

Ответ 4

Просто переместите фигурные скобки вне круглых скобок:

 {([^}]*)}

Ответ 5

Это регулярное выражение для С#.net.

@"{(.*?)}"

отображает

token1 token2

Ответ 6

Если я понимаю, чего вы хотите. Измените регулярное выражение на {([^}]*)}. Это будет захватывать текст между {}, не включая их.

Ответ 7

Немного изменив ответ @Milosz Krajewski

(?<=\{)[^}{]*(?=\})

это пропустит средние одинарные открывающие и закрывающие фигурные скобки в строке.