我正在尝试为基本计算器制作各种正则表达式。该字符串将由字符+ - * /
和整数组成,遵循以下结构。
n1 + n2 – n3 * n4 / n5 …
目的是让我+ -
在一年级只介绍2位数字的运算和数字,而在其他课程中,它允许我+ - * /
介绍更多数字的4个基本运算和数字。
代码
private void TextBoxOperation_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
var text = TextBoxOperation.Text + e.Text;
if (SelectedGrade == 1)
{
var regexItem = new Regex(@"[ ]{0,1}[0-9]{1,2}[-+ ]{0,2}");
e.Handled = !regexItem.IsMatch(text);
}
else if (SelectedGrade == 2)
{
var regexItem = new Regex(@"[ ]{0,1}[0-9]{1,3}[-+*\/ ]{0,2}");
e.Handled = !regexItem.IsMatch(text);
}
//...
}
一年级
Entrada | Salida
n + n | true
n - n | true
n * n | false
n / n | false
nn + n - n | true
n + nn - n | true
n + n - nn | true
nnn + n - n | false
nnnn + n - n| false
二年级
Entrada | Salida
n + n | true
n - n | true
n * n | true
n / n | true
nn + n - n | true
n + nn - n | true
n + n - nn | true
nnn + n - n | true
nnnn + n - n| false
更新
如果使用[0-9*+-\/ ]
它总是返回true。问题是它允许我输入多个字符++, +-, ...
、多个空格并且我无法控制数字的数量。我还注意到e.Text只返回最后一个char。
报酬
如果除上述之外,它还允许使用空格和括号。
Entrada | Salida
) | false
( | true
(+ | false
( + | false
() | false
( n | true
( n + | true
(n+n) | true
( n + n ) | true
nn + (n – n) | true
(n + nn) – n | true
(n + n) – nn)) | false
((n + n) – nn)) | true
我希望有一个人可以帮助我。谢谢。
正则表达式的解决方案
尝试以下正则表达式用于一级情况。允许平衡括号和空格:
^(?!.*\([ \t]*\))(?!.*[+-][ \t]*[+-])(?!.*\([ \t]*[+-])(?!.*[+-][ \t]*\))(?:[+-]|\b\d{1,2}\b|[ \t])*(?:(?:(?'open'\()(?:[+-]|\b\d{1,2}\b|[ \t])*)+(?:(?'-open'\)?)(?:[+-]|\b\d{1,2}\b|[ \t])*)+)*\s*$
你在这里有一个演示。
对于二级情况,您可以使用另一个:
^(?!.*\([ \t]*\))(?!.*[+/*-][ \t]*[+/*-])(?!.*\([ \t]*[+/*-])(?!.*[+/*-][ \t]*\))(?:[+/*-]|\b\d{1,3}\b|[ \t])*(?:(?:(?'open'\()(?:[+/*-]|\b\d{1,3}\b|[ \t])*)+(?:(?'-open'\)?)(?:[+/*-]|\b\d{1,3}\b|[ \t])*)+)*\s*$
解释:
两者都基于 .NET 正则表达式的“平衡组”功能。我推荐这本关于平衡组的读物。他们会比我在这里更好地解释自己。
在同一页面上,建议使用正则表达式来搜索平衡括号,其间有任何字符(括号除外)。
表达式是这样的:
^[^()]*(?>(?>(?'open'\()[^()]*)+(?>(?'-open'\))[^()]*)+)+(?(open)(?!))$
在这里,我们将做一些改变。我们将首先制作可选的右括号,因为我们的文本在输入时可能是有效的。此外,我们将删除条件,如果它发现更多的开放而不是封闭的括号,它将中止(通过总是失败的前瞻)。
此外,由于右括号现在是可选的,我们将原子组更改为普通组,因为我们需要能够进行回溯。
因此,更改后它看起来像这样:
^[^()]*(?:(?:(?'open'\()[^()]*)+(?:(?'-open'\)?)[^()]*)+)+$
但是您必须继续进行更改:
我们将允许以下选项之一,而不是允许括号之间的任何内容:
[+-]
[\t ]
\b\d{1,2}\b
所有这些都可以从 0 次重复到更多次,所以在括号之间我们可以得到类似的东西
1+1+1-2
,但也可以得到错误的东西,比如+++++
. 但我们稍后会解决这个问题。目前正则表达式如下所示:
^(?:[+-]|\b\d{1,2}\b|[ \t])*(?:(?:(?'open'\()(?:[+-]|\b\d{1,2}\b|[ \t])*)+(?:(?'-open'\)?)(?:[+-]|\b\d{1,2}\b|[ \t])*)+)*$
最后,为避免上述可能出现的错误内容,我们将在正则表达式的开头添加使用前瞻进行的验证。我们将排除所有可能发生的错误情况。什么:
(?!.*\([ \t]*\))
(?!.*[+-][ \t]*[+-])
(?!.*\([ \t]*[+-])
(?!.*[+-][ \t]*\))
这就是我们获得最终正则表达式的方式:
^(?!.*\([ \t]*\))(?!.*[+-][ \t]*[+-])(?!.*\([ \t]*[+-])(?!.*[+-][ \t]*\))(?:[+-]|\b\d{1,2}\b|[ \t])*(?:(?:(?'open'\()(?:[+-]|\b\d{1,2}\b|[ \t])*)+(?:(?'-open'\)?)(?:[+-]|\b\d{1,2}\b|[ \t])*)+)*\s*$
对于第二个正则表达式,我们将 all 更改
[+-]
为[+/*-]
以允许其余操作。我们还将更改\b{1,2}\b
by\b{1,3}\b
以允许最多三位数字。