С# 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();
Ответы
Ответ 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
(?<=\{)[^}{]*(?=\})
это пропустит средние одинарные открывающие и закрывающие фигурные скобки в строке.