【问题标题】:Find all but the first occurrence of a character with REGEX使用 REGEX 查找除第一次出现的字符之外的所有字符
【发布时间】:2010-11-26 16:35:21
【问题描述】:

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

到目前为止,我一直在使用在线 RegEx 工具来尝试一次性实现这一目标,但我并没有走得太远。

我希望做到这一点:

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}/./;

标签: .net regex


【解决方案1】:

这可以在单个正则表达式中完成,至少在支持lookbehind assertions 内部无限重复的 .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.

(?&lt;!^[^.]*) 表示:断言不可能匹配从输入字符串的开头开始并且仅由点以外的字符组成的字符串。此条件适用于第一个点之后的所有点。

【讨论】:

  • 谢谢,这个例子教会了我一些关于正则表达式的知识。
  • 谢谢,我也学到了一些新东西!在阅读后向断言的链接之前,我无法理解该示例!这也帮助了我!
【解决方案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());

【讨论】:

  • 谢谢,我很欣赏这个答案。我什至没有想过尝试这种逻辑。我希望我能接受 2 个答案。
【解决方案3】:

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

替换后,您可以尝试以下操作:

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

但只有当号码中有. 时,你才需要这个。

希望这会有所帮助。

【讨论】:

  • 感谢您修复第一部分。根据regexpal.com,您的第二个正则表达式将匹配所有 123.123.123.123 是预期的效果吗?我以前没见过“\1”。
  • 嗯,第二个正则表达式应该全部匹配,然后用 \1 替换它(这应该是第一个子模式,() 中的部分)只留下 123.123 - 除非 .NET 使用不同的正则表达式系统比我习惯的!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-07
  • 2023-02-25
  • 2018-07-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多