Регулярное выражение работает не так, как ожидалось.Замена - PullRequest
0 голосов
/ 02 сентября 2010

Я вытаскиваю волосы над следующей функцией:

Public Function SetVersion(ByVal hl7Message As String, ByVal newVersion As String) As String
    Dim rgx = New Regex("^(?<pre>.+)(\|\d\.\d{1,2})$", RegexOptions.Multiline)
    Dim m = rgx.Match(hl7Message)
    Return rgx.Replace(hl7Message, "${pre}|" & newVersion, 1, 0)
End Function

Для простоты я проверяю следующие данные:

dsfdsaf|2.1
wretdfg|2.2
sdafasd3|2.3

Что мне нужно сделать, это заменить «| 2.1» в строке first другим значением, скажем «| 2.4». Вместо этого происходит то, что «| 2.3» заменяется в последней строке. Это как если бы я не указал режим Multi-Line. Кроме того, следующий онлайн-инструмент вернул правильные совпадения. Итак, любой, кто может увидеть ошибку в моем регулярном выражении или коде, пожалуйста, укажите это.

Ответы [ 3 ]

2 голосов
/ 02 сентября 2010

Указав $, вы по существу соответствует последнему вхождению в конце строки. Если вы хотите сопоставить первое вхождение, удалите $ или укажите, что ожидается новая строка:

"^(?<pre>.+)(\|\d\.\d{1,2})"

или

"^(?<pre>.+)(\|\d\.\d{1,2})[\r\n]"

Исходя из вашего комментария об использовании Multiline и внешнего вида ваших тестовых данных, я полагаю, что вы вводите в несколько строк. Используйте вышеуказанный шаблон и попробуйте это:

Dim input As String = "dsfdsaf|2.1" & Environment.NewLine & _
                       "wretdfg|2.2" & Environment.NewLine & _
                       "sdafasd3|2.3"

Console.WriteLine("Before:")
Console.WriteLine(input)
Console.WriteLine("After:")
Console.WriteLine(SetVersion(input, "2.4"))

2,1 должен измениться на 2,4.

2 голосов
/ 02 сентября 2010

Ахмад Магид избил меня до этого. Удаление $ требуется. В следующем коде распечатаны ваши 3 строки, причем 2.1 соответствует первому совпадению.

class Program
{
    static void Main(string[] args)
    {
        string myData = "dsfdsaf|2.1" + Environment.NewLine +
                        "wretdfg|2.2" + Environment.NewLine + 
                        "sdafasd3|2.3";

        Regex rex = new Regex(@"^(?<pre>.+)(\|\d\.\d{1,2})",RegexOptions.Multiline);
        var m = rex.Matches(myData);
        foreach (var match in m)
        {
            string hello = match.ToString();
        }
    }
}
0 голосов
/ 02 сентября 2010

Вы можете использовать '?' сделать «+» ленивым вместо жадного. Он будет захватывать как можно меньше символов, все еще выполняя регулярное выражение.

Dim rgx = New Regex("^(?<pre>.+?)(\|\d\.\d{1,2})$", RegexOptions.Multiline)

Если вы знаете, что текст, предшествующий номеру версии, не будет содержать никаких каналов, вы также можете заменить. с классом символов [^ \ |].

Dim rgx = New Regex("^(?<pre>[^\|]+)(\|\d\.\d{1,2})$", RegexOptions.Multiline)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...