2012-01-18 6 views
3

проблема!

У меня есть следующие входные (правила) из плоского файла (речь о цифровом входе):C# регулярное выражение проблема

  • Ввод может быть натуральное число (ниже 1000): 1, 10, 100, 999, ...
  • Input может быть разделенный запятыми номер, окруженный кавычками (выше 1000): "1,000", "2,000", "3,000", "10,000", ...

у меня есть следующее регулярное выражение для проверки ввода: (?:(\d+)|\x22([0-9]+(?:,[0-9]+)*)\x22), поэтому для входа как 10 я ожидал в первом ма tching group 10, что я и получил. Но когда я получил вход, как "10,000", я ожидаю в первой группе сопоставлений 10,000, но он сохраняется во второй группе соответствия.

Пример
string text1 = "\"" + "10,000" + "\""; 
string text2 = "50"; 

string pattern = @"(\d+)|\x22([0-9]+(?:,[0-9]+){0,})\x22"; 

Match match1 = Regex.Match(text1, pattern); 
Match match2 = Regex.Match(text2, pattern); 

if (match1.Success) 
{ 
    Console.WriteLine("Match#1 Group#1: " + match1.Groups[1].Value); 
    Console.WriteLine("Match#1 Group#2: " + match1.Groups[2].Value); 

    # Outputs 
    # Match#1 Group#1: 
    # Match#1 Group#2: 10,000 
} 

if (match2.Success) 
{ 
    Console.WriteLine("Match#2 Group#1: " + match2.Groups[1].Value); 
    Console.WriteLine("Match#2 Group#2: " + match2.Groups[2].Value); 

    # Outputs 
    # Match#2 Group#1: 50 
    # Match#2 Group#2: 
} 

Ожидаемые результаты

Оба результата на одной и той же группе соответствия, в данном случае 1

Вопросы?

  • Что я делаю неправильно? Я просто получаю плохую группировку из матчей регулярных выражений.
  • Кроме того, я использую filehelpers .NET для анализа файла, есть ли другой способ решить эту проблему. Фактически я пытаюсь реализовать собственный конвертер.

Файл Объект

[FieldConverter(typeof(OOR_Quantity))] 
public Int32 Quantity; 

OOR_Quantity

internal class OOR_Quantity : ConverterBase 
{ 
    public override object StringToField(string from) 
    { 
     string pattern = @"(?:(\d+)|\x22([0-9]+(?:,[0-9]+)*)\x22)"; 
     Regex regex = new Regex(pattern); 

     if (regex.IsMatch(from)) 
     { 
      Match match = regex.Match(from); 
      return int.Parse(match.Groups[1].Value); 
     } 

     throw new ... 
    } 
} 

ответ

5

Номера групп назначаются исключительно на основе их позиции в регулярном выражении - конкретно, относительное положение открывающий кронштейн, (. В вашем регулярном выражении (\d+) является первой группой, а ([0-9]+(?:,[0-9]+)*) - второй.

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

@"(?:(?<NUMBER>\d+)|\x22(?<NUMBER>[0-9]+(?:,[0-9]+)*)\x22)" 

Теперь вы можете восстановить захваченное значение как match.Groups["NUMBER"].Value.

+0

Я не знаю, действительно ли я забыл об этом, или если я полностью неправильно понял правило. Благодаря! – Eder

0

Я проверил регулярное выражение ниже с Ruby:

text1 = "\"10,000\"" 
text2 = "50" 

regex = /"?([0-9]+(?:,[0-9]+){0,})"?/ 

text1 =~ regex 
puts "#$1" 

text2 =~ regex 
puts "#$1" 

Результат:

10,000 
50 

Я думаю, что можно переписать в C#. Разве вам этого недостаточно?

+0

Хороший и простой ответ, но вы не заставляете двойные кавычки появляться или нет. – Eder

Смежные вопросы