Найти все, кроме первого появления символа с REGEX

Я создаю приложение .Net, и мне нужно удалить любой десятичный символ из строки (исключая первый '.'). По сути, я очищаю пользовательский ввод, чтобы заставить результат реального числа.

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

Я хочу сделать это:

asd123.asd123.123.123 = 123.123123123

к сожалению, мне удалось добраться только до стадии, где

asd123.asd123.123.123 = 123.123.123.123

С помощью настоящий кодекс.

System.Text.RegularExpressions.Regex.Replace(str, "[^.|d]*", "")

но я застрял, пытаясь удалить все, кроме первой десятичной точки.

можно ли это сделать за один проход?
Есть ли лучший способ™?

3 ответов


Это можно сделать в одном регулярном выражении, по крайней мере, в .NET, который поддерживает бесконечное повторение внутри lookbehind утверждения:

resultString = Regex.Replace(subjectString, @"(?<!^[^.]*)\.|[^\d.]", "");

объяснение:

(?<!^[^.]*) # Either match (as long as there is at least one dot before it)
\.          # a dot
|           # or
[^\d.]      # any characters except digits or dots.

(?<!^[^.]*) значит: утверждать, что невозможно найти строку, которая начинается в начале входной строки и состоит исключительно из символов, отличных от точки. Это условие справедливо для всех точек, следующих за первой.


Я думаю, что это будет сделано лучше, без регулярных выражений.

string str = "asd123.asd123.123.123";
StringBuilder sb = new StringBuilder();
bool dotFound = false;
foreach (var character in str)
{
    if (Char.IsDigit(character))
        sb.Append(character);
    else if (character == '.')
        if (!dotFound)
        {
            dotFound = true;
            sb.Append(character);
        }
}
Console.WriteLine(sb.ToString());

во-первых, регулярное выражение, которое вы используете в настоящее время, оставит любые | символы нетронутыми. Вам нужно только [^.\d]* С . не имеет особого значения в []

после этой замены вы можете попробовать что-то вроде этого:

Replace(str, "([\d]+\.[\d]+)[^\d].*", "");

но вам понадобится только это, если есть . вообще в номере.

надеюсь, что это помогает.