какое регулярное выражение я должен использовать, чтобы разделить это? - PullRequest
2 голосов
/ 21 марта 2012

Я очень новичок в c # ..

я хочу программу, если ввод такой

ввод: There are 4 numbers in this string 40, 30, and 10

вывод:

there = string
are = string
4 = number
numbers = string
in = string
this = string
40 = number
, = symbol
30 = number
, = symbol
and = string
10 = number

Я попробую это

{
    class Program
    {
        static void Main(string[] args)
        {
            string input = "There are 4 numbers in this string 40, 30, and 10.";
            // Split on one or more non-digit characters.
            string[] numbers = Regex.Split(input, @"(\D+)(\s+)");
            foreach (string value in numbers)
            {
                Console.WriteLine(value);               
            }
        }
    }
}

но вывод отличается от того, что я хочу .. пожалуйста, помогите мне .. я застрял: ((

Ответы [ 5 ]

2 голосов
/ 21 марта 2012

Парсер регулярных выражений имеет условное условие if и возможность группировать элементы в именованные группы захвата;на что я покажу.

Вот пример, в котором паттерн сначала ищет символы (, только запятая добавляет больше символов в набор [,] ), затем цифры и переводит остальные слова в слова.

string text = @"There are 4 numbers in this string 40, 30, and 10";
string pattern = @"
(?([,])            # If a comma (or other then add it) is found its a symbol
  (?<Symbol>[,])   # Then match the symbol
 |                 # else its not a symbol
  (?(\d+)             # If a number
    (?<Number>\d+)    # Then match the numbers
   |                  # else its not a number
    (?<Word>[^\s]+)   # So it must be a word.
   ) 
)
";


// Ignore pattern white space allows us to comment the pattern only, does not affect
// the processing of the text!
Regex.Matches(text, pattern, RegexOptions.IgnorePatternWhitespace)
     .OfType<Match>()
     .Select (mt => 
    {
        if (mt.Groups["Symbol"].Success)
            return  "Symbol found:     " + mt.Groups["Symbol"].Value;

        if (mt.Groups["Number"].Success) 
            return  "Number found:  " + mt.Groups["Number"].Value;

        return "Word found:     " + mt.Groups["Word"].Value;
    }
     )
     .ToList() // To show the result only remove
     .ForEach(rs => Console.WriteLine (rs));

/* Result
Word found:     There
Word found:     are
Number found:  4
Word found:     numbers
Word found:     in
Word found:     this
Word found:     string
Number found:  40
Symbol found:     ,
Number found:  30
Symbol found:     ,
Word found:     and
Number found:  10
*/

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

Обсуждаю регулярное выражение, если оно условно для моего блога Регулярные выражения и Условное условие информация.

1 голос
/ 21 марта 2012

Вы можете разделить, используя этот шаблон: @"(,)\s?|\s"

Это разделяет запятую, но сохраняет ее, так как она находится внутри группы. \s? служит для соответствия необязательному пробелу, но исключает его из результата. Без этого разделение будет включать пространство, которое произошло после запятой. Далее, есть чередование для разделения на пробел в целом.

Чтобы классифицировать значения, мы можем взять первый символ строки и проверить тип, используя статические Char методы.

string input = "There are 4 numbers in this string 40, 30, and 10";
var query = Regex.Split(input, @"(,)\s?|\s")
                 .Select(s => new
                 {
                     Value = s,
                     Type = Char.IsLetter(s[0]) ?
                             "String" : Char.IsDigit(s[0]) ?
                             "Number" : "Symbol"
                 });
foreach (var item in query)
{
    Console.WriteLine("{0} : {1}", item.Value, item.Type);
}

Чтобы использовать метод Regex.Matches, можно использовать этот шаблон: @"\w+|,"

var query = Regex.Matches(input, @"\w+|,").Cast<Match>()
                 .Select(m => new
                 {
                     Value = m.Value,
                     Type = Char.IsLetter(m.Value[0]) ?
                             "String" : Char.IsDigit(m.Value[0]) ?
                             "Number" : "Symbol"
                 });
0 голосов
/ 21 марта 2012

Хорошо, чтобы соответствовать всем числам, которые вы могли бы сделать:

[\d]+

Для строк:

[a-zA-Z]+

А для некоторых символов, например

 [,.?\[\]\\\/;:!\*]+
0 голосов
/ 21 марта 2012

Вы можете очень легко сделать это так:

string[] tokens = Regex.Split(input, " ");  

foreach(string token in tokens)  
{  
    if(token.Length > 1)  
    {   
       if(Int32.TryParse(token))  
       {  
          Console.WriteLine(token + " =   number");
       }
      else  
      {  
         Console.WriteLine(token + " = string");  
      }  
    }    
    else  
    {
      if(!Char.isLetter(token ) && !Char.isDigit(token))   
      {  
        Console.WriteLine(token + " = symbol");
      }  
  }
}  

У меня нет удобной среды IDE, чтобы проверить, что это компилируется. По сути, что вы делаете, это разбить входные данные на пробел, а затем выполнить некоторые сравнения, чтобы определить, является ли это символ, строка или число.

0 голосов
/ 21 марта 2012

Если вы хотите получить числа

var reg = new Regex(@"\d+");
var matches = reg.Matches(input );
var numbers = matches
        .Cast<Match>()
        .Select(m=>Int32.Parse(m.Groups[0].Value));

Чтобы получить вывод:

var regSymbols = new Regex(@"(?<number>\d+)|(?<string>\w+)|(?<symbol>(,))");
var sMatches = regSymbols.Matches(input );
var symbols = sMatches
    .Cast<Match>()
    .Select(m=> new
    {                  
       Number = m.Groups["number"].Value,
       String = m.Groups["string"].Value,
       Symbol = m.Groups["symbol"].Value
     })
    .Select(
      m => new 
      {
        Match = !String.IsNullOrEmpty(m.Number) ? 
                    m.Number : !String.IsNullOrEmpty(m.String) 
                            ? m.String : m.Symbol,
        MatchType = !String.IsNullOrEmpty(m.Number) ? 
                    "Number" : !String.IsNullOrEmpty(m.String) 
                            ? "String" : "Symbol"
      }
    );

edit Если символов больше, чем запятой, вы можетесгруппируйте их в класс, как это сделал @Bogdan Emil Mariesan, и регулярное выражение будет:

@"(?<number>\d+)|(?<string>\w+)|(?<symbol>[,.\?!])"

edit2 Чтобы получить строки с =

var outputLines = symbols.Select(m=>
                            String.Format("{0} = {1}", m.Match, m.MatchType));
...