Проблема с регулярным выражением в C # - PullRequest
3 голосов
/ 18 января 2012

Проблема!

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

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

У меня есть следующее регулярное выражение для проверки ввода: (?:(\d+)|\x22([0-9]+(?:,[0-9]+)*)\x22), поэтому для ввода, подобного 10, я ожидаю в первой соответствующей группе 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 ...
    }
}

Ответы [ 2 ]

5 голосов
/ 18 января 2012

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

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

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

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

0 голосов
/ 18 января 2012

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

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

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

text1 =~ regex
puts "#$1"

text2 =~ regex
puts "#$1"

Результат:

10,000
50

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

...