【问题标题】:Regex in C# to process a textC# 中的正则表达式处理文本
【发布时间】:2017-07-13 19:23:16
【问题描述】:

我正在尝试删除一些文本并仅保留字符串中的小文本。
其实我对正则表达式很陌生,我读过一篇文章并没有很好地理解它。
这是我的文本示例(单独字符串对象中的每一行)

2015-03-08 10:30:00     /user841/column-width
2015-03-08 10:30:01     /user849/connect
2015-03-08 10:30:01     /user262/open-level2-price/some other text
2015-03-08 10:30:01     /user839/open-detailed-quotes

我想在 c# 中使用正则表达式处理它们并得到以下输出:

column-width
connect
open-level2-price/some other text
open-detailed-quotes

我已使用以下行来执行此操作,但它会引发异常:

Match match = Regex.Match(line, @"*./user\d+/*.");

例外:

System.ArgumentException: '正在解析 "*./user\d+/*." - 量词 {x,y} 什么都没有。'

谁能帮忙!

【问题讨论】:

  • 欢迎来到 Stack Overflow。请阅读How to Ask 以及如何制作Minimal, Complete, and Verifiable example
  • 您说“我正在尝试删除一些文本”。你是怎么做到的?为什么你认为它不起作用?您标记了这个“C#”,但我在这里没有看到任何 C# 代码。 SO 是一个问答网站,“有人可以帮忙吗?” is not a question we can answer.
  • 你不需要正则表达式
  • @DourHighArch 我已经编辑了问题,请重新阅读编辑。 :)
  • ^.*/ 替换为空。

标签: c# regex


【解决方案1】:

您得到的错误是由于您尝试量化模式的开始这一事实引起的,这在 .NET 正则表达式中被视为错误。也许,您打算使用 .* 而不是 *.(贪婪地匹配任何 0+ 字符,尽可能多),但从预期结果来看,这肯定不是您需要的。

你需要

/user\d+/(.*)

regex demo

详情

  • /user - 文字子字符串 /user
  • \d+ - 1 个或多个数字(使用 RegexOptions.ECMAScript 选项仅在 .NET 正则表达式中将 ASCII 数字与 \d 匹配)
  • / - 文字 /
  • (.*) - 正在捕获组 #1,它匹配除换行符以外的任何 0+ 个字符(将 * 替换为 + 以匹配至少 1 个字符)。

C#:

var results = Regex.Matches(s, @"/user\d+/(.*)")
    .Cast<Match>()
    .Select(m => m.Groups[1].Value)
    .ToList();

【讨论】:

    【解决方案2】:

    不使用正则表达式,只需拆分 '/' 字符并使用数组的最后一个索引(使用 LINQ):

    string inputString = "2015-03-08 10:30:01     /user262/open-level2-price";
    inputString.Split('/').Last();
    

    Split 返回一个字符串数组,在您的情况下,字符串数组上方的示例输入如下所示:

    array[0] = "2015-03-08 10:30:01     "
    array[1] = "user262"
    array[2] = "open-level2-price"
    

    您表示您总是想要最后一部分,所以只需使用 LINQ 获取数组的 .Last() 索引。

    小提琴here

    【讨论】:

    • 是的,这很好,但问题是我不保证我想要的文本没有任何斜线。
    • @O-BL 我很困惑,您的正则表达式专门寻找斜杠。如果您不能保证会有斜线,那么您的正则表达式将如何工作?
    • 输入字符串可能是这样的 2015-03-08 10:30:01 /user262/open-level2-price/some other text 和输出应该是这样的 open-level2-price/some other text ,所以常规形式是:日期然后是“用户”字然后是用户编号。跨度>
    • 嗯好吧,那是有道理的
    【解决方案3】:

    这里有一个简单的例子来说明如何使用 Regex.Replace 静态方法。

    https://dotnetfiddle.net/JuUF9E

    using System;
    using System.Text.RegularExpressions;
    
    public class Program
    {
        public static void Main()
        {
            string[] lines = new string[] {
                "2015-03-08 10:30:00     /user841/column-width",
                "2015-03-08 10:30:01     /user849/connect",
                "2015-03-08 10:30:01     /user262/open-level2-price",
                "2015-03-08 10:30:01     /user839/open-detailed-quotes"
            };
    
            string pattern = @"(.*/.*/)(.*)";
    
            string replacement = "$2";
    
            foreach(var line in lines)
            {
                Console.WriteLine(Regex.Replace(line, pattern, replacement));
            }
        }
    }
    

    【讨论】:

      【解决方案4】:

      我不知道你为什么要尝试用正则表达式做这个简单的事情,你只需要阅读这些行并用'\'分隔,他们选择最后一个索引就是这样。例如,如果您在文件中包含该数据,则可以使用以下内容:

      string newString = "";
      StreamReader sr = new StreamReader('log.txt');
      while(!sr.ReadLine)
      {
         string[] splitted = sr.ReadLine().Split('/');
         if(splitted.Length > 0)
              newString += splitted[splitted.Length - 1];
      }
      sr.Close();
      

      最后,newString 变量将包含您想要的内容。否则,您可以添加列表中的每一行,前提是您要对数据进行一些处理。

      【讨论】:

        【解决方案5】:

        Look around 怎么样

        var line = "2015-03-08 10:30:01     /user839/open-detailed    otes/dsada/dsa/das/dsadsa";
        
        //  dsadsa
        var match = Regex.Match(line, @"(?!.*/).*").Value;
        

        【讨论】:

        • 这给了我一个错误。实际上@WiktorStribiżew 已经回答了这个问题。谢谢你。 :)
        • 更新,缺少“匹配”
        • 感谢帮助,我认为输出字符串应该是open-detailed otes/dsada/dsa/das/dsadsa
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-12-03
        • 2015-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-02-05
        • 1970-01-01
        相关资源
        最近更新 更多