正则表达式忽略 9 次出现的特殊字符“|”

nav*_*147 6 regex symbols

需要正则表达式来解析日志行,我必须在第 10 次出现管道符号后选择数据 |

示例日志行;

Info     device  Allow:FWD|TCP|data1|data2|data3|data4|data5|data6|data7|data8|data9|data10|data11|0|1|0|0|0|0||||||
Run Code Online (Sandbox Code Playgroud)

我必须从上面的日志行中选择 data9。

下面是我现在使用的表达式,这是针对 Java 程序的

表达:

\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|([^|]*)\|
Run Code Online (Sandbox Code Playgroud)

选择组 11

而不是一一转义字符想跳过/忽略10个管道符号并选择 data9

Tot*_*oto 30

这就是量词的用途。

^(?:[^|]*\|){10}([^|]*)
Run Code Online (Sandbox Code Playgroud)

  • @OlivierGrégoire:你的正则表达式需要 [117 步](https://regex101.com/r/skLgN6/1),我的 [37 步](https://regex101.com/r/D7nwKn/1) (9认同)
  • `[^|]*` 肯定更快,因为没有回溯的可能性。我什至可能会使用`[^|\n]` 来确保正则表达式不会在一行的末尾运行(例如,如果一行由于任何原因少于 10 个字段)。 (2认同)

Jus*_*tin 21

如果您在另一种编程语言(Python、C# 等)的上下文中使用正则表达式,则该语言可能具有某种类型的字符串拆分功能。根据我的经验,通常更容易在分隔符上拆分并获取值列表/数组,而不是使用正则表达式进行拆分。

  • 例如,C# 在 split str.Split(new []{'|'}, 10) 中有参数(或者“|”.ToCharArray()),并使用 str.Split('|')[10..] 进行索引如果你也想把余数分开。这些解决方案通常比正则表达式运行得更快,因此对于可以使用它们的简单情况,它可能是更好的选择。当然,如果您需要复杂性,那么正则表达式可能会更好,但对于这种情况,拆分函数可能更适合。 (7认同)
  • @Nelson “这仅适用于非常简单的单个字符拆分。” - 就像问题中给出的例子一样。 (2认同)