使用正则表达式查找除第一个出现的字符以外的所有字符

9

我正在开发一个.Net应用程序,需要从字符串中去除任何非十进制字符(不包括第一个“.”)。基本上,我正在清理用户输入以强制得到实数结果。

到目前为止,我一直在使用在线正则表达式工具尝试在单个步骤中实现此操作,但是我没有取得很大进展。

我希望能够实现以下内容:

asd123.asd123.123.123 = 123.123123123

不幸的是,我只能达到这个阶段

asd123.asd123.123.123 = 123.123.123.123

通过使用这段代码。
System.Text.RegularExpressions.Regex.Replace(str, "[^\.|\d]*", "")

但是我卡在了只保留第一个小数点的问题上。

这能否一次完成?
有更好的方法吗?™


s/[.]/\x{DEADBEEF}/; s/[^.\d\x{DEADBEEF}]//g; s/\x{DEADBEEF}/./; - tchrist
3个回答

6

这可以在单个正则表达式中完成,至少在支持无限重复的.NET中,在后顾断言内部:

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.

(?<!^[^.]*) 的意思是:断言无法匹配一个字符串,该字符串从输入字符串的开头开始,且仅由除点以外的字符组成。对于第一个点之后的所有点,此条件为真。


1
谢谢,这个例子教会了我很多关于正则表达式的知识。 - Mike
谢谢,我也学到了新东西!在阅读后向断言的链接之前,我无法理解这个例子!这也帮助了我! - Tim Lewis

2

我觉得如果不使用正则表达式的话,这件事情会做得更好。

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());

谢谢,我很感激这个答案。我甚至没有想过尝试这种逻辑。我希望我能接受两个答案。 - Mike

0

首先,您目前使用的正则表达式将保留任何 | 字符。您只需要 [^.\d]*,因为在 []. 没有特殊含义。

进行此替换后,您可以尝试类似以下的内容:

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

但只有在数字中有.时才需要这个。

希望这可以帮到你。


感谢修复第一部分。根据http://regexpal.com/,您的第二个正则表达式将匹配所有的123.123.123.123,这是期望的效果吗?我以前没有见过“\1”被使用过。 - Mike
嗯,第二个正则表达式应该匹配所有内容,然后用\1(应该是第一个子模式,在'()'中的部分)替换它,只留下123.123 ——除非.NET使用与我所用的不同的正则表达式系统! - Niet the Dark Absol

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接