Пример соответствия c # regex - PullRequest
52 голосов
/ 20 января 2011

Пытаетесь получить значения, используя следующий текст, какие-либо мысли, что это можно сделать с помощью Regex?

Введите

Lorem ipsum dolor sit% download% # 456 amet, conceptetur adipiscing% download% # 3434 elit. Duis non nunc nec mauris feugiat porttitor. Sed tincidunt blandit dui a viverra% download% # 298. Aenean dapibus nisl% download% # 893434 id nibh auctor vel tempor velit blandit.

выход

456  
3434  
298   
893434 

Заранее спасибо.

Ответы [ 6 ]

59 голосов
/ 20 января 2011

Итак, вы пытаетесь получить числовые значения, которым предшествует токен "% download% #"?

Попробуйте этот шаблон:

(?<=%download%#)\d+

Это должно работать. Я не думаю, что # или % - это специальные символы в .NET Regex, но вам придется либо избегать обратной косой черты, например \\, либо использовать дословную строку для всего шаблона:

var regex = new Regex(@"(?<=%download%#)\d+");
return regex.Matches(strInput);

Проверено здесь: http://rextester.com/BLYCC16700

ПРИМЕЧАНИЕ: Подтверждающее утверждение (?<=...) важно, потому что вы не хотите включать %download%# в свои результаты, только цифры после него. Тем не менее, ваш пример требует этого перед каждой строкой, которую вы хотите захватить. Группа lookbehind удостоверится, что она есть во входной строке, но не включит ее в возвращаемые результаты. Подробнее об утверждениях здесь.

38 голосов
/ 20 января 2011

Все остальные ответы, которые я вижу, в порядке, но C # поддерживает именованные группы!

Я бы использовал следующий код:

const string input = "Lorem ipsum dolor sit %download%#456 amet, consectetur adipiscing %download%#3434 elit. Duis non nunc nec mauris feugiat porttitor. Sed tincidunt blandit dui a viverra%download%#298. Aenean dapibus nisl %download%#893434 id nibh auctor vel tempor velit blandit.";

static void Main(string[] args)
{
    Regex expression = new Regex(@"%download%#(?<Identifier>[0-9]*)");
    var results = expression.Matches(input);
    foreach (Match match in results)
    {
        Console.WriteLine(match.Groups["Identifier"].Value);
    }
}

Код, который гласит: (?<Identifier>[0-9]*) указывает, что результаты [0-9]* будут частью именованной группы, которую мы проиндексировали, как указано выше: match.Groups["Identifier"].Value

4 голосов
/ 31 августа 2013
    public void match2()
    {
        string input = "%download%#893434";
        Regex word = new Regex(@"\d+");
        Match m = word.Match(input);
        Console.WriteLine(m.Value);
    }
2 голосов
/ 21 ноября 2014

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

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

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;

public class Info
{
    public String Identifier;
    public char nextChar;
};

class testRegex {

    const string input = "Lorem ipsum dolor sit %download%#456 amet, consectetur adipiscing %download%#3434 elit. " +
    "Duis non nunc nec mauris feugiat porttitor. Sed tincidunt blandit dui a viverra%download%#298. Aenean dapibus nisl %download%#893434 id nibh auctor vel tempor velit blandit.";

    static void Main(string[] args)
    {
        Regex regex = new Regex(@"%download%#(?<Identifier>[0-9]*)(?<nextChar>.)(?<thisCharIsNotNeeded>.)");
        List<Info> infos = new List<Info>();

        foreach (Match match in regex.Matches(input))
        {
            Info info = new Info();
            for( int i = 1; i < regex.GetGroupNames().Length; i++ )
            {
                String groupName = regex.GetGroupNames()[i];

                FieldInfo fi = info.GetType().GetField(regex.GetGroupNames()[i]);

                if( fi != null ) // Field is non-public or does not exists.
                    fi.SetValue( info, Convert.ChangeType( match.Groups[groupName].Value, fi.FieldType));
            }
            infos.Add(info);
        }

        foreach ( var info in infos )
        {
            Console.WriteLine(info.Identifier + " followed by '" + info.nextChar.ToString() + "'");
        }
    }

};

Этот механизм использует отражение C #, чтобы установить значение для класса.имя группы сопоставляется с именем поля в экземпляре класса.Обратите внимание, что Convert.ChangeType не будет принимать никакого вида мусора.

Если вы хотите добавить отслеживание строки / столбца - вы можете добавить дополнительное разделение Regex для строк, но для того, чтобы сохранить цикл без изменений -все шаблоны соответствия должны иметь именованные группы.(В противном случае индекс столбца будет вычислен неправильно)

Это приведет к следующему выводу:

456 followed by ' '
3434 followed by ' '
298 followed by '.'
893434 followed by ' '
0 голосов
/ 20 января 2011
Regex regex = new Regex("%download#(\\d+?)%", RegexOptions.SingleLine);
Matches m = regex.Matches(input);

Я думаю, что добьется цели (не проверено).

0 голосов
/ 20 января 2011

Этот шаблон должен работать:

#\d

foreach(var match in System.Text.RegularExpressions.RegEx.Matches(input, "#\d"))
{
    Console.WriteLine(match.Value);
}

(я не нахожусь перед Visual Studio, но даже если он не компилируется как есть, он должен быть достаточно близко, чтобы настроить что-то, что работает).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...