繁体   English   中英

自定义正则表达式替换模式

[英]Customized Regex replace pattern

在我的应用程序上,我必须解析一个文件并替换一些字符串。

1 not intressting "some string with " " !"
2 not intressting "some string" ; "commentar"
3 not intressting ;"no string to replace"

对于结果,我希望从一行的第一行到最后一行的整个字符串。 分号后面到行尾的整个字符串将被忽略。

结果使第一个和最后一个退出。

1 "some string with " " !"
2 "some string"
3 no match

我的正则表达式模式适用于所有带引号的字符串,但是如何实现分号选择呢?

(?<=^.*?\")(.*)(?=\".*?$)

编辑

(?<=^[^;]*?\")(.*)(?=\".*?$)

如果使用分号,则此正则表达式将查找期望的第一引号和最后引号之间的所有字符串。 但是我怎么发现中间的分号呢?

not intressting "some text" ;comment "not intressting"

比赛

'some text'

假设条件

匹配定义为一个序列:

  • 从输入字符串中的第一个"开始。让我们称其为“ 1st "或“ opening "
  • 没有; 开幕前"
  • ; 如果序列中的最后一个"是奇数,则从1st开始" ,则允许在序列中使用。
  • ; 如果序列中的最后一个"从第1个数字开始算起"是偶数,则不允许在该序列中使用。
  • 以满足上述条件的最远的"结尾。

使用此正则表达式(原始表单)查找第一个匹配项:

^(?>[^;"]*)"((?>(?>"[^";]*(?="[^"]*$)|"[^";]*"|[^"]*)+))"

在C#字符串文字中:

"^(?>[^;\"]*)\"((?>(?>\"[^\";]*(?=\"[^\"]*$)|\"[^\";]*\"|[^\"]*)+))\""

结果将在第一个捕获组中。

说明

语法说明:

  • (?>pattern)是非回溯/所有子表达式。 它可以防止引擎回溯。 这是一种优化形式。
  • (?=pattern)为零宽度正向前。 它检查前面的字符串是否符合该pattern而不消耗文本。
  • | 是交替的。 我在这里要注意的是,正则表达式控制引擎将从左到右检查每个规则,如果找到匹配项,则不会考虑其他规则。 这意味着顺序对于确定匹配至关重要。
  • 我认为您已经熟悉了其余的内容,因为它们非常基础。

为了说明起见,我将使用原始正则表达式,并删除非回溯优化:

^[^;"]*"((?:"[^";]*(?="[^"]*$)|"[^";]*"|[^"]*)+)"

由于要求“一行中的第一和最后一个引号”,每行最多有1个匹配项。

通过对需求进行分析,我们知道感兴趣部分之前的文本不应包含; (部分需求)或" (否则引号不会是第一个)。因此,我们可以编写^[^;"]*来从字符串开头锚定匹配项,并将所有内容匹配到第一个引号"

这是带引号的字符串部分,为便于说明而分解:

"
(
(?:
"[^";]*(?="[^"]*$)
|
"[^";]*"
|
[^"]*
)+
)
"

让我们专注于这三个片段,我将自下而上地开始解释:

"[^";]*(?="[^"]*$)
"[^";]*"
[^"]*

对于这里的所有情况,我们遇到的最后一个引号始终是一个奇数引号。

  • [^"]* :确保最后一个引号是单引号,因此我们可以包含; ,但不能包含"
  • "[^";]*" :最后一个引号是奇数引号,此后也是奇数引号。该部分处理偶数引号后的部分,其中不允许;
  • "[^";]*(?="[^"]*$) :这是棘手的部分,它处理字符串的引号为奇数(> = 3)的情况。 我确保在双引号之后没有; 并接着最后一个引号"字符串中。‘其次是最后一个引号"字符串中的”与先行取得(?="[^"]*$)

片段"[^";]*(?="[^"]*$)必须放在"[^";]*"前面,以避免回溯,以便我们可以应用非回溯优化。

试试看:

        string[] lines = File.ReadAllLines(@"Data.txt");
        string[] lines2 = lines
            .Select(line => Regex.Match(line, @"(?<!;)""((.(?!;\s*""))*)""", RegexOptions.None).Groups[1].Value)
            .Select(line => line.Length > 0 ? line : "no match")
            .ToArray();

此正则表达式可以解释为: 取以引号开头但不立即以分号开头,且后接模式分号-空白(引号)和引号结尾的文本

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM