假设
匹配被定义为一个序列:
- 从
"输入字符串中的第一个开始。让我们称之为第一次"或开幕"。 
;开场前没有" 
;序列中允许,如果序列中的最后一个"是奇数,则从第一个开始计数"。 
;不允许在序列中,如果序列中的最后一个"是偶数,则从第一个开始计数"。 
"以满足上述条件的最远结束。 
解决方案
使用此正则表达式(原始形式)查找第一个匹配项:
^(?>[^;"]*)"((?>(?>"[^";]*(?="[^"]*$)|"[^";]*"|[^" ]*)+))"
在 C# 字符串文字中:
"^(?>[^;\"]*)\"((?>(?>\"[^\";]*(?=\"[^\"]*$)|\"[^\";]*\"|[^\"]*)+))\""
结果将在第一个捕获组中。
解释
语法解释:
(?>pattern)是非回溯/占有子表达式。它可以防止引擎回溯。这是一种优化形式。 
(?=pattern)是零宽度正前瞻。pattern它在不消耗文本的情况下检查前面的字符串是否符合。 
|是交替。这里我要注意的是,正则表达式引擎会从左到右检查每个规则,如果找到匹配项,则不会考虑其他规则。这意味着顺序在确定匹配时很重要。 
- 我假设您熟悉其余部分,因为它们非常基础。
 
为了解释起见,我将使用原始正则表达式,去掉非回溯优化:
^[^;"]*"((?:"[^";]*(?="[^"]*$)|"[^";]*"|[^"]*)+)"
由于要求“一行中的第一个和最后一个引号”,每行最多有 1 个匹配项。
通过对需求进行一些分析,我们知道感兴趣部分之前的文本不应该包含;(需求的一部分)或"(否则,引用不会是第一个)。因此,我们可以编写^[^;"]*以从字符串的开头锚定匹配并匹配所有内容,直到第一个引号"。
这是引用的字符串部分,为了便于解释而分解:
"
(
(?:
"[^";]*(?="[^"]*$)
|
"[^";]*"
|
[^"]*
)+
)
"
让我们关注这3个片段,我将从下往上开始解释:
"[^";]*(?="[^"]*$)
"[^";]*"
[^"]*
对于这里的所有情况,我们遇到的最后一个报价总是一个奇怪的报价。
[^"]*: 最后一个引号保证是奇数引号,所以我们可以有任何东西,包括;,但除了". 
"[^";]*": 最后一个引号是奇引号,后面也是奇引号。这部分处理偶数引用之后的部分,其中;不允许。 
"[^";]*(?="[^"]*$):这是棘手的部分,它处理字符串有奇数个引号(> = 3)的情况。我确保在偶数引号之后,没有字符串中;的最后一个引号"。“后跟"字符串中的最后一个引号”是通过前瞻实现的(?="[^"]*$)。 
片段"[^";]*(?="[^"]*$)必须放在前面"[^";]*"以避免回溯,这样我们才能应用非回溯优化。