0

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

1 不关注“一些带有”的字符串!”
2 不关注“一些字符串”;“评论员”
3 not intressting ;"没有要替换的字符串"

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

结果没有第一个和最后一个 qoutes。

1 "一些带有 " " 的字符串!"
2“一些字符串”
3 不匹配

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

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

编辑

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

如果前导分号,此正则表达式将查找第一个和最后一个引号之间的所有字符串。但是我是怎么找到分号的呢?

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

比赛

'some text'
4

2 回答 2

0

假设

匹配被定义为一个序列:

  • "输入字符串中的第一个开始。让我们称之为第一次"或开幕"
  • ;开场前没有"
  • ;序列中允许,如果序列中的最后一个"是奇数,则从第一个开始计数"
  • ;不允许在序列中,如果序列中的最后一个"是偶数,则从第一个开始计数"
  • "以满足上述条件的最远结束。

解决方案

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

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

在 C# 字符串文字中:

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

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

解释

语法解释:

  • (?>pattern)是非回溯/占有子表达式。它可以防止引擎回溯。这是一种优化形式。
  • (?=pattern)是零宽度正前瞻。pattern它在不消耗文本的情况下检查前面的字符串是否符合。
  • |是交替。这里我要注意的是,正则表达式引擎会从左到右检查每个规则,如果找到匹配项,则不会考虑其他规则。这意味着顺序在确定匹配时很重要。
  • 我假设您熟悉其余部分,因为它们非常基础。

为了解释起见,我将使用原始正则表达式,去掉非回溯优化:

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

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

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

这是引用的字符串部分,为了便于解释而分解:

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

让我们关注这3个片段,我将从下往上开始解释:

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

对于这里的所有情况,我们遇到的最后一个报价总是一个奇怪的报价。

  • [^"]*: 最后一个引号保证是奇数引号,所以我们可以有任何东西,包括;,但除了".
  • "[^";]*": 最后一个引号是奇引号,后面也是奇引号。这部分处理偶数引用之后的部分,其中;不允许。
  • "[^";]*(?="[^"]*$):这是棘手的部分,它处理字符串有奇数个引号(> = 3)的情况。我确保在偶数引号之后,没有字符串中;的最后一个引号"“后跟"字符串中的最后一个引号”是通过前瞻实现的(?="[^"]*$)

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

于 2013-03-04T08:36:36.433 回答
0

试试这个:

        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();

此正则表达式可以解释为:获取以引号开头但前面没有分号且后面没有模式分号-空格-引号并以引号结尾的文本

于 2013-03-04T08:50:12.237 回答