- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在编写一个函数解析引擎,它使用正则表达式来分隔各个术语(定义为常量或变量,后跟(可选)运算符)。它工作得很好,除非我在其他分组术语中对术语进行分组。这是我正在使用的代码:
//This matches an opening delimiter
Regex openers = new Regex("[\\[\\{\\(]");
//This matches a closing delimiter
Regex closers = new Regex("[\\]\\}\\)]");
//This matches the name of a variable (\w+) or a constant numeric value (\d+(\.\d+)?)
Regex VariableOrConstant = new Regex("((\\d+(\\.\\d+)?)|\\w+)" + FunctionTerm.opRegex + "?");
//This matches the binary operators +, *, -, or /
Regex ops = new Regex("[\\*\\+\\-/]");
//This compound Regex finds a single variable or constant term (including a proceeding operator,
//if any) OR a group containing multiple terms (and their proceeding operators, if any)
//and a proceeding operator, if any.
//Matches that match this second pattern need to be added to the function as sub-functions,
//not as individual terms, to ensure the correct evalutation order with parentheses.
Regex splitter = new Regex(
openers +
"(" + VariableOrConstant + ")+" + closers + ops + "?" +
"|" +
"(" + VariableOrConstant + ")" + ops + "?");
当“splitter”匹配字符串“4/(2*X*[2+1])”时,匹配的值为“4/”、“2*”、“X*”、“2” +”和“1”,完全忽略所有定界括号和大括号。我相信这是因为“拆分器”正则表达式的后半部分(“|”之后的部分)正在匹配并覆盖模式的另一部分。这很糟糕——我希望分组表达式优先于单个术语。有谁知道我该怎么做?我研究过使用正面/负面前瞻和后视,但老实说我不确定如何使用它们,或者它们的用途,就此而言,我找不到任何相关的例子......提前致谢.
最佳答案
您没有向我们展示您是如何应用正则表达式的,所以这是我制作的演示:
private static void ParseIt(string subject)
{
Console.WriteLine("subject : {0}\n", subject);
Regex openers = new Regex(@"[[{(]");
Regex closers = new Regex(@"[]})]");
Regex ops = new Regex(@"[*+/-]");
Regex VariableOrConstant = new Regex(@"((\d+(\.\d+)?)|\w+)" + ops + "?");
Regex splitter = new Regex(
openers + @"(?<FIRST>" + VariableOrConstant + @")+" + closers + ops + @"?" +
@"|" +
@"(?<SECOND>" + VariableOrConstant + @")" + ops + @"?",
RegexOptions.ExplicitCapture
);
foreach (Match m in splitter.Matches(subject))
{
foreach (string s in splitter.GetGroupNames())
{
Console.WriteLine("group {0,-8}: {1}", s, m.Groups[s]);
}
Console.WriteLine();
}
}
输出:
subject : 4/(2*X*[2+1])
group 0 : 4/
group FIRST :
group SECOND : 4/
group 0 : 2*
group FIRST :
group SECOND : 2*
group 0 : X*
group FIRST :
group SECOND : X*
group 0 : [2+1]
group FIRST : 1
group SECOND :
如您所见,术语 [2+1]
与正则表达式的第一部分匹配,如您所愿。但是,它不能对 (
做任何事情,因为紧随其后的下一个括号字符是另一个“开场白”([
),它正在寻找一个“closer” .
您可以使用 .NET 的“平衡匹配”功能来允许包含在其他组中的分组术语,但这不值得付出努力。正则表达式不是为解析而设计的——事实上,解析和正则表达式匹配是根本不同的操作。这是区别的一个很好的例子:正则表达式主动寻找匹配项,跳过它不能使用的任何东西(比如你的例子中的左括号),但是解析器必须检查每个字符(即使它只是为了决定忽略它)。
关于演示:我尝试进行最少的功能更改以使您的代码正常工作(这就是为什么我没有更正将 +
在捕获组之外),但我也进行了一些表面更改,这些更改代表了积极的建议。即:
@"..."
)(我认为原因很明显)。ExplicitCapture
选项让您不必在任何地方用 (?:...)
弄乱正则表达式需要一个非捕获组。最后,从一堆较小的正则表达式构建大型正则表达式的整个方案在 IMO 上的用处非常有限。跟踪各部分之间的交互非常困难,例如哪个部分在哪个组中。 C# 的逐字字符串的另一个优点是它们是多行的,因此您可以利用自由间距模式(又名 /x
或 COMMENTS 模式):
Regex r = new Regex(@"
(?<GROUPED>
[[{(] # opening bracket
( # group containing:
((\d+(\.\d+)?)|\w+) # number or variable
[*+/-]? # and proceeding operator
)+ # ...one or more times
[]})] # closing bracket
[*+/-]? # and proceeding operator
)
|
(?<UNGROUPED>
((\d+(\.\d+)?)|\w+) # number or variable
[*+/-]? # and proceeding operator
)
",
RegexOptions.ExplicitCapture | RegexOptions.IgnorePatternWhitespace
);
这不是为了解决您的问题;正如我所说,这不是正则表达式的工作。这只是一些有用的正则表达式技术的演示。
关于c# - 如何在 Regex 中指定匹配模式的优先级?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4425195/
使用sed和/或awk,仅在行包含字符串“ foo”并且行之前和之后的行分别包含字符串“ bar”和“ baz”时,我才希望删除行。 因此,对于此输入: blah blah foo blah bar
例如: S1: "some filename contains few words.txt" S2:“一些文件名包含几个单词 - draft.txt” S3:“一些文件名包含几个单词 - 另一个 dr
我正在尝试处理一些非常困惑的数据。我需要通过样本 ID 合并两个包含不同类型数据的大数据框。问题是一张表的样本 ID 有许多不同的格式,但大多数都包含用于匹配其 ID 中某处所需的 ID 字符串,例如
我想在匹配特定屏幕尺寸时显示特定图像。在这种情况下,对于 Bootstrap ,我使用 col-xx-## 作为我的选择。但似乎它并没有真正按照我认为应该的方式工作。 基本思路,我想显示一种全屏图像,
出于某种原因,这条规则 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*
我想做类似的东西(Nemerle 语法) def something = match(STT) | 1 with st= "Summ" | 2 with st= "AVG" =>
假设这是我的代码 var str="abc=1234587;abc=19855284;abc=1234587;abc=19855284;abc=1234587;abc=19855284;abc=123
我怎样才能得到这个字符串的数字:'(31.5393701, -82.46235569999999)' 我已经在尝试了,但这离解决方案还很远:) text.match(/\((\d+),(\d+)\)/
如何去除输出中的逗号 (,)?有没有更好的方法从字符串或句子中搜索 url。 alert(" http://www.cnn.com df".match(/https?:\/\/([-\w\.]+
a = ('one', 'two') b = ('ten', 'ten') z = [('four', 'five', 'six'), ('one', 'two', 'twenty')] 我正在尝试
我已经编写了以下代码,我希望用它来查找从第 21 列到另一张表中最后一行的值,并根据这张表中 A 列和另一张表中 B 列中的值将它们返回到这张表床单。 当我使用下面的代码时,我得到一个工作表错误。你能
我在以下结构中有两列 A B 1 49 4922039670 我已经能够评估 =LEN(A1)如2 , =LEFT(B1,2)如49 , 和 =LEFT(B1,LEN(A1)
我有一个文件,其中一行可以以 + 开头, -或 * .在其中一些行之间可以有以字母或数字(一般文本)开头的行(也包含这些字符,但不在第 1 列中!)。 知道这一点,设置匹配和突出显示机制的最简单方法是
我有一个数据字段文件,其中可能包含注释,如下所示: id, data, data, data 101 a, b, c 102 d, e, f 103 g, h, i // has to do with
我有以下模式:/^\/(?P.+)$/匹配:/url . 我的问题是它也匹配 /url/page ,如何忽略/在这个正则表达式中? 该模式应该: 模式匹配:/url 模式不匹配:/url/page 提
我有一个非常庞大且复杂的数据集,其中包含许多对公司的观察。公司的一些观察是多余的,我需要制作一个键来将多余的观察映射到一个单独的观察。然而,判断他们是否真的代表同一家公司的唯一方法是通过各种变量的相似
我有以下 XML A B C 我想查找 if not(exists(//Record/subRecord
我制作了一个正则表达式来验证潜在的比特币地址,现在当我单击报价按钮时,我希望根据正则表达式检查表单中输入的值,但它不起作用。 https://jsfiddle.net/arkqdc8a/5/ var
我有一些 MS Word 文档,我已将其全部内容转移到 SQL 表中。 内容包含多个方括号和大括号,例如 [{a} as at [b],] {c,} {d,} etc 我需要进行检查以确保括号平衡/匹
我正在使用 Node.js 从 XML 文件读取数据。但是当我尝试将文件中的数据与文字进行比较时,它不匹配,即使它看起来相同: const parser: xml2js.Parser = new
我是一名优秀的程序员,十分优秀!