正则表达式:匹配除括号(C#)内的词以外的所有词

正则表达式:匹配除括号(C#)内的词以外的所有词,c#,regex,lookbehind,C#,Regex,Lookbehind,因此: COLUMN_1, COLUMN_2, COLUMN_3, ((COLUMN_1) AS SOME TEXT) AS COLUMN_4, COLUMN_5 我将如何获得以下匹配项: COLUMN_1 COLUMN_2 COLUMN_3 COLUMN_4 COLUMN_5 我试过: (?<!(\(.*?\)))(\w+)(,\s*\w+)*? (? 但我觉得我太离谱了:(我正在使用regexstorm.net进行测试 感谢您的帮助:)这应该可以: (?<!\()COLUM

因此:

COLUMN_1, COLUMN_2, COLUMN_3, ((COLUMN_1) AS SOME TEXT) AS COLUMN_4, COLUMN_5
我将如何获得以下匹配项:

COLUMN_1
COLUMN_2
COLUMN_3
COLUMN_4
COLUMN_5
我试过:

(?<!(\(.*?\)))(\w+)(,\s*\w+)*?
(?
但我觉得我太离谱了:(我正在使用regexstorm.net进行测试

感谢您的帮助:)

这应该可以:

(?<!\()COLUMN_[\d](?!\))

此处演示:

您需要一个正则表达式来跟踪开始和结束括号,并确保只有在后面有一组平衡的括号(或根本没有括号)时才匹配单词:

Regex regexObj=新的Regex(
@“\w+#匹配一个单词
(?=#仅当可能匹配以下条件时:
(?>#原子组(用于避免灾难性回溯):
[^()]+#匹配除括号外的任何字符
|#或
\(?)#a(,增加深度计数器
|#或
\)(?)#a),减小深度计数器
)*#任意次数。
(?(深度)(?!)#然后确保深度计数器再次为零
$#在字符串的末尾。
)#(前瞻断言的结束)“,
RegexOptions.ignorepattern(空格);

我试图提供一个指向regexstorm.net的测试链接,但对于StackOverflow来说太长了。显然,SO也不喜欢URL缩短器,所以我无法直接链接,但您应该能够轻松地重新创建链接:
http://bit[点]ly/2cNZS0O

因为有嵌套的括号,所以事情变得更加棘手。尽管.NET正则表达式引擎提供了使用堆栈内存的平衡组构造,但我使用了一种更通用的方法,称为递归匹配

正则表达式:

\((?(?!\(|\)).|(?R))*\)|(\w+)

你所需要的只是第一个捕获组

交替左侧的说明:

\(           # Match an opening bracket
(?(?!\(|\))  # If next character is not `(` or `)`
    .             # Then match it
    |             # Otherwise
    (?R)          # Recurs whole pattern
)*           # As much as possible
\)           # Up to corresponding closing bracket
匹配除一组单词外的所有单词是正则表达式最困难的练习之一。简单的方法是:构造一个有限自动机,它接受关于它应该接受的字符串的原始非否定谓词,然后将所有接受状态更改为非接受状态,最后构造一个正则表达式ar表达式,相当于刚刚构造的自动机。这是一项很难完成的任务,因此处理它的最简单方法是为要求反的谓词构造regexp,并将字符串传递给regexp匹配器,如果它匹配,只需拒绝它

这样做的主要问题是,计算机很容易做到这一点,但从自动机描述构造正则表达式非常繁琐,通常不会得到想要的结果(实际上是一个巨大的结果)。让我用一个例子来说明:

您要求匹配单词,但从这些单词中,您需要的是不在一组单词中出现的单词。假设我们需要与该组单词精确匹配的自动机,并假设我们已匹配该单词的第一个
n-1
字母。应该匹配此字符串,但前提是您下一个没有得到最后一个字母。因此,正确的regexp应该是一个匹配第一个单词但最后一个单词的所有字母的regexp。不,如果我们有一个单词匹配第一个单词但最后两个单词中的所有字母,然后依次返回到第一个字母,我们可以跳过这个测试(显然,如果您的regexp不是以单词的第一个字母开头,它无论如何都不匹配)让我们假设第一个单词是
begin
。与
begin
不相等的东西匹配的好regexp如下:

[^B]|B[^E]|BE[^G]|BEG[^I]|BEGI[^N]
(0)---[a-zA-Z]--->((1))---[a-zA-Z]--.
 ^ \               |  ^             |
 |  *              *  |             |
 `--+<-------------'  `-------------'
另一种情况(使事情更加复杂)是,如果字符串中不包含单词
BEGIN
,则查找与字符串匹配的regexp。让我们从相反的谓词开始,查找包含单词
BEGIN
的字符串

让我们构造它的有限自动机:

(0)---B--->(1)---E--->(2)---G--->(3)---I--->(4)---N--->((5))
 ^ \        |          |          |          |           ^ \
 | |        |          |          |          |           | |
 `-+<-------+<---------+<---------+<---------'           `-+
应该是一个很好的候选者。它应该符合如下自动机定义:

[^B]|B[^E]|BE[^G]|BEG[^I]|BEGI[^N]
(0)---[a-zA-Z]--->((1))---[a-zA-Z]--.
 ^ \               |  ^             |
 |  *              *  |             |
 `--+<-------------'  `-------------'
(0)——[a-zA-Z]——>((1))——[a-zA-Z]——。
^ \               |  ^             |
|  *              *  |             |

`--+
(COLUMN\u 1
COLUMN\u 1)
的结果应该是什么?如果它在括号中,它应该被忽略:)谢谢!所以
(COLUMN\u 1
/
COLUMN\u 1)
不应该被忽略?(COLUMN\u 1/COLUMN\u 1)将被忽略,因为它在括号中。为什么不在预期输出中提到
作为
?我认为它也是括号外的一个词。我只是尝试了(?好,这只是括号之间的内容(使用regexstorm,我正在使用C#Regex).我想把它从原稿中排除,所以我认为这是非常接近的lol!唷…好吧,我会研究一下,Tim.Regex和我相处得不太好-我开始觉得我已经掌握了它,它又咬了我一口!感谢解释得很好的答案。@John:我刚刚看了regexstorm.net(以前不知道);似乎你不能只单击那里的“IgnorePatternWhitespace”复选框,但你可以使用
(?x)
内联修饰符。我现在在我的答案中提供了一个测试链接。@John,你可以通过单击答案左侧的绿色复选标记来感谢人们。@Dour High Arch-我想是的,谢谢提醒:)这是我见过的最好的答案之一,我喜欢你记录每一行来解释。如果我能给你额外的分数,我会的,非常感谢!Revo,当我尝试使用regexstorm.net时,我得到了无法识别的分组结构:(.NET正则表达式不支持递归,只支持平衡组。对不起,我以为.NET中有递归,但它们不支持。@John
((0))--B-->((1))--E-->((2))--G-->((3))--I-->((4))--N-->(5)
 ^ \         |          |          |          |         ^ \
 | |         |          |          |          |         | |
 `-+<--------+<---------+<---------+<---------'         `-+
[a-zA-Z][a-zA-Z]*
(0)---[a-zA-Z]--->((1))---[a-zA-Z]--.
 ^ \               |  ^             |
 |  *              *  |             |
 `--+<-------------'  `-------------'