Фестиваль функциональной регрессии Regex - реконструируйте конкретную строку из этой разделанной - PullRequest
2 голосов
/ 10 января 2012

В:

53_2_b
50
48_1_b_i
50A_3_b
48_1_b_iv

Из:

53(2)(b)
50
48(1)(b)(i)
50A(3)(b)
48(1)(b)(iv)

(Это ссылки на разделы из законодательства, которые были преобразованы в NCNames. Я хочу преобразовать их.)

Есть ли какой-то неловко небольшой объем кода для этого, который многому меня научит?

Это то, что у меня сейчас есть:

readonly Func<char, bool> _isNotUnderscore = c => c != '_';

string ConvertFragmentToSecRef(string frag)
{           
    var p0 = new Regex(@"^[0-9]+[A-Z]*");
    var p1 = new Regex(@"[0-9]+");
    var p2 = new Regex(@"[\w]+");
    var p3 = new Regex(@"(i|v|x)+");

    var regexes = new[] {p0, p1, p2, p3};

    var sb = new StringBuilder();

    Recurse(frag,0,ref regexes,ref sb);

    return sb.ToString();
}

void Recurse(string left,int level, ref Regex[] regexes,ref StringBuilder sb)
{
    if (level < 4)
    {
        var head = String.Concat(left.TakeWhile(_isNotUnderscore));
        var tail = String.Concat(left.Skip(head.Count())).TrimStart('_');
        if (regexes[level].IsMatch(head))
        {
            sb.Append(level == 0 ? head : "(" + head + ")");
            Recurse(tail, level + 1, ref regexes, ref sb);
        }
    }
}

1 Ответ

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

Для этого вам не нужна рекурсия, просто предварительные утверждения :

resultString = Regex.Replace(subjectString, 
    @"_          # match _
    ([^_\r\n]*)  # match whatever follows except _ or newlines
    (?=[_\r]|$)  # assert that a _ or end-of-line follows", 
    "($1)", RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace);

Это работает с вашей многострочной строкой ввода.Конечно, если у вас есть каждая строка в отдельной строке, это проще:

resultString = Regex.Replace(subjectString, 
    @"_      # match _
    ([^_]*)  # match whatever follows except _
    (?=_|$)  # assert that a _ or end-of-string follows", 
    "($1)", RegexOptions.IgnorePatternWhitespace);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...