【问题标题】:Find consesutive lines in a string starting with "pipe"在以“管道”开头的字符串中查找连续行
【发布时间】:2019-03-25 06:29:17
【问题描述】:

我对正则表达式很陌生,并且搜索并尝试了几个小时以找到以下问题的解决方案。

我有一个这样的字符串:

|Text1|Text2|Text3\n|Text4|Text5|Text6\nSomething else\n|Text6|Text8|Text9\n

有几行文本(其中行表示换行符),其中一些以| 开头(可能包括其他管道)。

我需要 C# 的 RegEx 的正则表达式,它提供以下组:

组 1:

|Text1|Text2|Text3\n|Text4|Text5|Text6\n

组2:

|Text6|Text8|Text9\n

换句话说:对于以| 开头的每一行,我都需要整行。如果有几行都以| 开头,我需要将这些行放在一组中。

这里要求一些额外的例子:

示例 1

以下输入

Text1|Text2\n

应该返回不匹配,因为没有以 | 开头的行

示例 2

以下输入

|Text1|Text2

应该返回不匹配,因为没有以\n结尾的行

示例 3

以下输入

sometext\n|Text1|Text2\nsometext

应该返回 1 个组

|Text1|Text2\n

因为该行以| 开头并以\n 结尾

示例 4

以下输入

sometext\n|someothertext\nsometext\n|someothertext\n

应该返回 2 个组

|someothertext\n

|someothertext\n

因为这两行以| 开头,以\n 结尾

示例 5

以下输入

sometext\n|someothertext\n|sometext\n|someothertext\n

应该返回 1 个组

|someothertext\n|sometext\n|someothertext\n

因为这三行都以| 开头并以\n 结尾,并且它们是连续的。

我发现以下 RegEx 匹配以 | 开头并以 \n 结尾的一行:

(?s)(\\n\|)((.*?)\\n)

但它不能识别连续的行。我知道我不知何故需要使用反向引用\1,但我还没有让它工作。

澄清:我的实际任务是增强 WPF 库 https://github.com/theunrepentantgeek/Markdown.XAML 的以下 Markdown 以便它支持表语法。

由于 WPF 库的降价是基于 IEnumerable 管道中使用的一组 RegEx 表达式,我想保持这种模式,只添加表格所需的部分。

markdown 中的表格由以管道开头的几行描述,其中表格的每一列由管道分隔。以管道开头的连续行属于一个表。每个“列”的内容(即一行中两个管道之间的值),可以是任何文本,甚至可以是另一个 markdown-expression。

markdown 的表格语法在此处描述https://www.tablesgenerator.com/markdown_tables

【问题讨论】:

  • 有趣的问题,虽然你的例子是晦涩难懂的。 . .例如,我不清楚 Test6 是否故意重复。如上所述,一些具体的例子会有所帮助。即使对于 RegEx 专业人士来说,这个问题也是一个挑战,因为“|”也是一个 RegEx 运算符,每次使用它时都需要加上引号,因为新行需要特殊选项,以便 RegEx 将整个事物视为一个输入。这是一个艰难的第一个问题。更多内容如下。
  • 对于这样的问题,我强烈推荐 RegEx Tester 。 . .一定要选择一个专门做 C# 的。在快速谷歌之后,我找到了这个:regexstorm.net/tester 我并不是说这个特定的好坏,只是说它是我很容易找到的。在这样的测试器中解决问题将使通过示例快速运行变得更加容易。当您看到 RegEx 的工作原理时,您将了解很多有关它的工作原理。提示一:反引号你所有的管道符号。提示二:我很确定您需要“多行”选项,但我留给您阅读文档。
  • 您好 Andreas,您添加的关于您要添加的功能的上下文在很大程度上无关紧要。包括您的代码是什么以及您迄今为止尝试过的正则表达式+代码解决方案的示例将有助于缩小您的问题并使其更容易回答。
  • 您正在尝试的内容并不适合纯正则表达式解决方案。 @AleksAndreev 是正确的,代码+正则表达式解决方案可能更合适。例如,使用匹配一个表行的正则表达式,并使用它一个代码循环来遍历输入,直到下一位数据不是您正在解析的当前表的新行。
  • 嗨,威尔,我不认为上下文无关紧要。 @AleksAndreev 表示正则表达式并不总是适合正则表达式,您也是如此(我同意),所以我添加了库要扩展的解释是基于正则表达式的,我想坚持下去图案。 Frank 发现我的示例晦涩难懂,因此我指出了我想要实现的功能以提供更多上下文。

标签: c# regex


【解决方案1】:

看起来您根本不需要 RegEx。只需将您的输入拆分为“\n”,然后以智能方式对您的行进行分组。试试这个代码:

var input = "|Text1|Text2|Text3\n|Text4|Text5|Text6\nSomething else\n|Text6|Text8|Text9\n";

var lines = input.Split(new[] {'\n'}, StringSplitOptions.RemoveEmptyEntries)
    .GroupAdjacent(line => line.StartsWith("|"))
    .Where(x => x.Key) // select only lines that starts with pipe
    .Select(g => string.Join("\n", g))
    .ToArray();

它使用来自MoreLinq 库的GroupAdjacent 方法

对于你的输入输出将是

【讨论】:

    猜你喜欢
    • 2022-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 2019-12-13
    • 2020-03-20
    • 1970-01-01
    相关资源
    最近更新 更多