有这样一组字符串例子~~~
string str1 = @"
if '年终奖' <> '年终奖' :
if 150 < 0 : 0
elif 150<=500 and 150>0 : 150*0.05-0-1554
elif 150<=2000 and 150>500 : 150*0.10-25-1554
elif 150<=5000 and 150>2000 : 150*0.15-125-1554
elif 150<=20000 and 150>5000 : 150*0.20-375-1554
elif 150<=40000 and 150>20000 : 150*0.25-1375-1554
else : -99999
elif '年终奖' == '年终奖' :
if 150 < 0 :
if (-9999+150)/12<=500 and (-9999+150)/12>0 : (-9999+150)/12*0.05-0
elif (-9999+150)/12<=2000 and (-9999+150)/12>500 : (-9999+150)/12*0.10-25
elif (-9999+150)/12<=5000 and (-9999+150)/12>2000 : (-9999+150)/12*0.15-125
elif (-9999+150)/12<=20000 and (-9999+150)/12>5000 : (-9999+150)/12*0.20-375
elif (-9999+150)/12<=40000 and (-9999+150)/12>20000 : (-9999+150)/12*0.25-1375
else : -99999
elif 150 > 0 :
if -9999/12<=500 and -9999/12>0 : -9999/12*0.05-0
elif -9999/12<=2000 and -9999/12>500 : -9999/12*0.10-25
elif -9999/12<=5000 and -9999/12>2000 : -9999/12*0.15-125
elif -9999/12<=20000 and -9999/12>5000 : -9999/12*0.20-375
elif -9999/12<=40000 and -9999/12>20000 : -9999/12*0.25-1375
else : -99999
else : -99999
";
要点:
1.从前缩进的空格数可以看出是否同组的if else。
2.顶层的if else 肯定是非空格开头的。
3.非顶层的同级的不同组的空格数不一定相同,如例子。
4.表达式规则一般有一下几种:
第一种:
if <条件> : <结果> _回车
elif <条件> : <结果> _回车
else : <结果>
这种情况一般<结果>是单个计算表达式,没有if else子逻辑运算表达式
第二种:
if <条件> : _回车
<结果> _回车
elif <条件> : _回车
<结果> _回车
else :
<结果>
这种<结果>一般是单个计算表达式或含有if else的子逻辑运算表达式
第三种:
混用的情况,如例子的顶层的if和最后的else。
5.存在只有if没有elif或else的情况。
6.<结果>内可能嵌套其他if else表达式,不过if else前肯定有缩进空格
7.if elif else肯定都是小写。需求很简单,想要通过正则表达式得到顶层的没有前空格的if elif else里的粗体<条件>部分和斜体<条件>的键值对数组,数组需要按表达式实际的if elif else顺序排好。
要考虑以上各种要点,以及4点所列的组合情况。先谢了!!!
string str1 = @"
if '年终奖' <> '年终奖' :
if 150 < 0 : 0
elif 150<=500 and 150>0 : 150*0.05-0-1554
elif 150<=2000 and 150>500 : 150*0.10-25-1554
elif 150<=5000 and 150>2000 : 150*0.15-125-1554
elif 150<=20000 and 150>5000 : 150*0.20-375-1554
elif 150<=40000 and 150>20000 : 150*0.25-1375-1554
else : -99999
elif '年终奖' == '年终奖' :
if 150 < 0 :
if (-9999+150)/12<=500 and (-9999+150)/12>0 : (-9999+150)/12*0.05-0
elif (-9999+150)/12<=2000 and (-9999+150)/12>500 : (-9999+150)/12*0.10-25
elif (-9999+150)/12<=5000 and (-9999+150)/12>2000 : (-9999+150)/12*0.15-125
elif (-9999+150)/12<=20000 and (-9999+150)/12>5000 : (-9999+150)/12*0.20-375
elif (-9999+150)/12<=40000 and (-9999+150)/12>20000 : (-9999+150)/12*0.25-1375
else : -99999
elif 150 > 0 :
if -9999/12<=500 and -9999/12>0 : -9999/12*0.05-0
elif -9999/12<=2000 and -9999/12>500 : -9999/12*0.10-25
elif -9999/12<=5000 and -9999/12>2000 : -9999/12*0.15-125
elif -9999/12<=20000 and -9999/12>5000 : -9999/12*0.20-375
elif -9999/12<=40000 and -9999/12>20000 : -9999/12*0.25-1375
else : -99999
else : -99999
";
要点:
1.从前缩进的空格数可以看出是否同组的if else。
2.顶层的if else 肯定是非空格开头的。
3.非顶层的同级的不同组的空格数不一定相同,如例子。
4.表达式规则一般有一下几种:
第一种:
if <条件> : <结果> _回车
elif <条件> : <结果> _回车
else : <结果>
这种情况一般<结果>是单个计算表达式,没有if else子逻辑运算表达式
第二种:
if <条件> : _回车
<结果> _回车
elif <条件> : _回车
<结果> _回车
else :
<结果>
这种<结果>一般是单个计算表达式或含有if else的子逻辑运算表达式
第三种:
混用的情况,如例子的顶层的if和最后的else。
5.存在只有if没有elif或else的情况。
6.<结果>内可能嵌套其他if else表达式,不过if else前肯定有缩进空格
7.if elif else肯定都是小写。需求很简单,想要通过正则表达式得到顶层的没有前空格的if elif else里的粗体<条件>部分和斜体<条件>的键值对数组,数组需要按表达式实际的if elif else顺序排好。
要考虑以上各种要点,以及4点所列的组合情况。先谢了!!!
解决方案 »
- mdi主体窗加了控件,如何让它不挡住子窗体
- 求教各位兄弟啊,c#网络编程(就光socket,tcplistener,完成端口)这种的有没什么相关优秀书籍可以介绍啊,在网上逛了半天,只看了一两本,提供的服务器写法性能也都不是很高,这方面的资源好像有点匮乏啊
- 怎么去除图片的只读属性呢
- c#
- 简单的问题
- 请问究竟什么是"模块"??我真的糊涂了~~.大虾帮帮忙~~~~~
- 关于想从某个子函数结束应用程序的问题。
- 刚学C#,问几个菜鸟问题
- C#怎么通过一个窗体的BUTTON按钮给另一个窗体的LISTVIEW添加一行
- [求助] 谁能提供 Visual studio.net 中文版的序列号。(企业架构版)
- (vs2005)webbrowser如何屏蔽脚本错误的提示?
- 关于DataGridView的提问
elif {应税额} <=500 and {应税额}>0 : {应税额}*0.05-0-{当月历史非年终奖非固定所得税}-{当月历史月工资所得税}
elif {应税额} <=2000 and {应税额}>500 : {应税额}*0.10-25-{当月历史非年终奖非固定所得税}-{当月历史月工资所得税}
elif {应税额} <=5000 and {应税额}>2000 : {应税额}*0.15-125-{当月历史非年终奖非固定所得税}-{当月历史月工资所得税}
elif {应税额} <=20000 and {应税额}>5000 : {应税额}*0.20-375-{当月历史非年终奖非固定所得税}-{当月历史月工资所得税}
elif {应税额} <=40000 and {应税额}>20000 : {应税额}*0.25-1375-{当月历史非年终奖非固定所得税}-{当月历史月工资所得税}
else : -99999"
key2 = "#类型# == '年终奖'" value2 =@" if {应税额} < 0 :
if (#奖金#+{应税额})/12 <=500 and (#奖金#+{应税额})/12>0 : (#奖金#+{应税额})/12*0.05-0
elif (#奖金#+{应税额})/12 <=2000 and (#奖金#+{应税额})/12>500 : (#奖金#+{应税额})/12*0.10-25
elif (#奖金#+{应税额})/12 <=5000 and (#奖金#+{应税额})/12>2000 : (#奖金#+{应税额})/12*0.15-125
elif (#奖金#+{应税额})/12 <=20000 and (#奖金#+{应税额})/12>5000 : (#奖金#+{应税额})/12*0.20-375
elif (#奖金#+{应税额})/12 <=40000 and (#奖金#+{应税额})/12>20000 : (#奖金#+{应税额})/12*0.25-1375
else : -99999
elif {应税额} > 0 :
if #奖金#/12 <=500 and #奖金#/12>0 : #奖金#/12*0.05-0
elif #奖金#/12 <=2000 and #奖金#/12>500 : #奖金#/12*0.10-25
elif #奖金#/12 <=5000 and #奖金#/12>2000 : #奖金#/12*0.15-125
elif #奖金#/12 <=20000 and #奖金#/12>5000 : #奖金#/12*0.20-375
elif #奖金#/12 <=40000 and #奖金#/12>20000 : #奖金#/12*0.25-1375
else : -99999"
key3 = "" value3 =@" -99999"
上面最后一个为空,是因为else里没有条件表达式。
@"(?msi)^(\s*)if\b(?<key1>.*?):(?<value1>.*?)(^\1elif\b(?<key2>.*?):(?<value2>.*?))*(^\1else\b(?<key3>.*?):?<value3>.*?))*"
using System.Text.RegularExpressions; class Test
{
static string str1 = @"
if '年终奖' <> '年终奖' :
if 150 < 0 : 0
elif 150 <=500 and 150>0 : 150*0.05-0-1554
elif 150 <=2000 and 150>500 : 150*0.10-25-1554
elif 150 <=5000 and 150>2000 : 150*0.15-125-1554
elif 150 <=20000 and 150>5000 : 150*0.20-375-1554
elif 150 <=40000 and 150>20000 : 150*0.25-1375-1554
else : -99999
elif '年终奖' == '年终奖' :
if 150 < 0 :
if (-9999+150)/12 <=500 and (-9999+150)/12>0 : (-9999+150)/12*0.05-0
elif (-9999+150)/12 <=2000 and (-9999+150)/12>500 : (-9999+150)/12*0.10-25
elif (-9999+150)/12 <=5000 and (-9999+150)/12>2000 : (-9999+150)/12*0.15-125
elif (-9999+150)/12 <=20000 and (-9999+150)/12>5000 : (-9999+150)/12*0.20-375
elif (-9999+150)/12 <=40000 and (-9999+150)/12>20000 : (-9999+150)/12*0.25-1375
else : -99999
elif 150 > 0 :
if -9999/12 <=500 and -9999/12>0 : -9999/12*0.05-0
elif -9999/12 <=2000 and -9999/12>500 : -9999/12*0.10-25
elif -9999/12 <=5000 and -9999/12>2000 : -9999/12*0.15-125
elif -9999/12 <=20000 and -9999/12>5000 : -9999/12*0.20-375
elif -9999/12 <=40000 and -9999/12>20000 : -9999/12*0.25-1375
else : -99999
else : -99999
"; static void Main()
{
string pattern = @"(?msix)
^(\s*)if\b(?<key1>.*?):(?<value1>.*?)
(^\1elif\b(?<key2>.*?):(?<value2>.*?))*
(^\1else\b(?<key3>.*?):(?<value3>.*))
";
MatchCollection mc = Regex.Matches(str1, pattern);
foreach (Match m in mc)
{
// 匹配到的第一个 if 的 key1 及 value1
string key1 = m.Groups["key1" ].Value.Trim();
string value1 = m.Groups["value1"].Value.Trim();
Console.WriteLine("Key1 = [{0}]", key1 );
Console.WriteLine("Value1 = [{0}]", value1);
// 匹配到的 elif 的 key2 及 value2 (可能有多个捕获组)
int i = 0;
foreach (Capture c in m.Groups["key2"].Captures)
{
string key2 = c.Value.Trim();
string value2 = m.Groups["value2"].Captures[i++].Value.Trim();
Console.WriteLine("Key2 = [{0}]", key2 );
Console.WriteLine("Value2 = [{0}]", value2);
} // 匹配到的 else 的 key3 及 value3
string key3 = m.Groups["key3" ].Value.Trim();
string value3 = m.Groups["value3"].Value.Trim();
Console.WriteLine("Key3 = [{0}]", key3 );
Console.WriteLine("Value3 = [{0}]", value3);
}
}
}
^(\s*)if\b(?<key1>.*?):(?<value1>.*?)
(^\1elif\b(?<key2>.*?):(?<value2>.*?))*
(^\1else\b(?<key3>.*?):(?<value3>.*))
";/*
这个表达式用 ^(\s*)if 记录了 if 前面的空格,
然后用 ^\1elif 反向引用 \1 指明必须匹配和前面的 if 同样多的前导空格,行末的 * 表明可以有0个或多个 elif,
最后, ^\1else 反向引用 \1 指明必须匹配和前面的 if 同样多的前导空格,但有个缺点是 else 是必须的。
*/
elif 150<=500 and 150>0 : 150*0.05-0-1554
elif 150<=2000 and 150>500 : 150*0.10-25-1554
elif 150<=5000 and 150>2000 : 150*0.15-125-1554
elif 150<=20000 and 150>5000 : 150*0.20-375-1554
elif 150<=40000 and 150>20000 : 150*0.25-1375-1554
else : -99999还有,下面的这个结果不正确。 string str1 = @"
if 150 < 0 :
if (-9999+150)/12<=500 and (-9999+150)/12>0 : (-9999+150)/12*0.05-0
elif (-9999+150)/12<=2000 and (-9999+150)/12>500 : (-9999+150)/12*0.10-25
elif (-9999+150)/12<=5000 and (-9999+150)/12>2000 : (-9999+150)/12*0.15-125
elif (-9999+150)/12<=20000 and (-9999+150)/12>5000 : (-9999+150)/12*0.20-375
elif (-9999+150)/12<=40000 and (-9999+150)/12>20000 : (-9999+150)/12*0.25-1375
else : -99999
elif 150 > 0 :
if -9999/12<=500 and -9999/12>0 : -9999/12*0.05-0
elif -9999/12<=2000 and -9999/12>500 : -9999/12*0.10-25
elif -9999/12<=5000 and -9999/12>2000 : -9999/12*0.15-125
elif -9999/12<=20000 and -9999/12>5000 : -9999/12*0.20-375
elif -9999/12<=40000 and -9999/12>20000 : -9999/12*0.25-1375
else : -99999
";
using System;
class Validation
{
public static void Main()
{
String strToTest;
Validation objValidate=new Validation(); Console.Write("Enter a String to Test for Alphabets:");
strToTest=Console.ReadLine();
if(objValidate.IsAlpha(strToTest))
{
Console.WriteLine("{0} is Valid Alpha String",strToTest);
}
else
{
Console.WriteLine("{0} is not a Valid Alpha String",strToTest);
}
}
public bool IsNaturalNumber(String strNumber)
{
Regex objNotNaturalPattern=new Regex("[^0-9]");
Regex objNaturalPattern=new Regex("0*[1-9][0-9]*"); return !objNotNaturalPattern.IsMatch(strNumber) &&
objNaturalPattern.IsMatch(strNumber);
}
public bool IsWholeNumber(String strNumber)
{
Regex objNotWholePattern=new Regex("[^0-9]"); return !objNotWholePattern.IsMatch(strNumber);
}
public bool IsInteger(String strNumber)
{
Regex objNotIntPattern=new Regex("[^0-9-]");
Regex objIntPattern=new Regex("^-[0-9]+$|^[0-9]+$"); return !objNotIntPattern.IsMatch(strNumber) &&
objIntPattern.IsMatch(strNumber);
}
public bool IsPositiveNumber(String strNumber)
{
Regex objNotPositivePattern=new Regex("[^0-9.]");
Regex objPositivePattern=new Regex("^[.][0-9]+$|[0-9]*[.]*[0-9]+$");
Regex objTwoDotPattern=new Regex("[0-9]*[.][0-9]*[.][0-9]*"); return !objNotPositivePattern.IsMatch(strNumber) &&
objPositivePattern.IsMatch(strNumber) &&
!objTwoDotPattern.IsMatch(strNumber);
}
public bool IsNumber(String strNumber)
{
Regex objNotNumberPattern=new Regex("[^0-9.-]");
Regex objTwoDotPattern=new Regex("[0-9]*[.][0-9]*[.][0-9]*");
Regex objTwoMinusPattern=new Regex("[0-9]*[-][0-9]*[-][0-9]*");
String strValidRealPattern="^([-]|[.]|[-.]|[0-9])[0-9]*[.]*[0-9]+$";
String strValidIntegerPattern="^([-]|[0-9])[0-9]*$";
Regex objNumberPattern =new Regex("(" + strValidRealPattern +")|(" + strValidIntegerPattern + ")"); return !objNotNumberPattern.IsMatch(strNumber) &&
!objTwoDotPattern.IsMatch(strNumber) &&
!objTwoMinusPattern.IsMatch(strNumber) &&
objNumberPattern.IsMatch(strNumber);
}
public bool IsAlpha(String strToCheck)
{
Regex objAlphaPattern=new Regex("[^a-zA-Z]"); return !objAlphaPattern.IsMatch(strToCheck);
} // Function to Check for AlphaNumeric. public bool IsAlphaNumeric(String strToCheck)
{
Regex objAlphaNumericPattern=new Regex("[^a-zA-Z0-9]"); return !objAlphaNumericPattern.IsMatch(strToCheck);
}
}
给一个我的“正则表达式”的例子,希望对你有所帮助。仅供参考!
// 改成这样就能正确处理没有 “最后的 else ” 的情况了:
string pattern = @"(?msix)
^(\s*)if\b(?<key1>.*?):(?<value1>.*?) # 匹配 if 并记录前导空格
(^\1elif\b(?<key2>.*?):(?<value2>.*?))* # 匹配对应的 elif ,0个或多个
(^\1else\b(?<key3>.*?):(?<value3>.*?))? # 匹配对应的 else ,0个或1个
\Z # 匹配整个字符串末尾
";
可以,只要把程序中的所有的 .Trim() 去掉就可以了: MatchCollection mc = Regex.Matches(str1, pattern);
foreach (Match m in mc)
{
// 匹配到的第一个 if 的 key1 及 value1
string key1 = m.Groups["key1" ].Value;
string value1 = m.Groups["value1"].Value;
Console.WriteLine("Key1 = [{0}]", key1 );
Console.WriteLine("Value1 = [{0}]", value1);
// 匹配到的 elif 的 key2 及 value2 (可能有多个捕获组)
int i = 0;
foreach (Capture c in m.Groups["key2"].Captures)
{
string key2 = c.Value;
string value2 = m.Groups["value2"].Captures[i++].Value;
Console.WriteLine("Key2 = [{0}]", key2 );
Console.WriteLine("Value2 = [{0}]", value2);
} // 匹配到的 else 的 key3 及 value3
string key3 = m.Groups["key3" ].Value;
string value3 = m.Groups["value3"].Value;
Console.WriteLine("Key3 = [{0}]", key3 );
Console.WriteLine("Value3 = [{0}]", value3);不过,有可能会有多余的回车(没关系,不会造成障碍)。
正则表达式选项可以使用影响匹配行为的选项修改正则表达式模式。可以通过下列两种基本方法之一设置正则表达式选项:可以在 Regex (pattern, options) 构造函数中的 options 参数中指定,其中 options 是 RegexOptions 枚举值的按位“或”组合;也可以使用内联 (?imnsx-imnsx:) 分组构造或 (?imnsx-imnsx) 其他构造在正则表达式模式内设置它们。在内联选项构造中,一个选项或一组选项前面的减号 (-) 用于关闭这些选项。例如,内联构造 (?ix-ms) 将打开 IgnoreCase 和 IgnorePatternWhiteSpace 选项而关闭 Multiline 和 Singleline 选项。默认情况下,关闭所有正则表达式选项。下表列出了 RegexOptions 枚举的成员以及等效的内联选项字符。请注意,选项 RightToLeft 和 Compiled 只适用于表达式整体而不允许内联。(它们只能在 Regex 构造函数的 options 参数中指定。) 选项 None 和 ECMAScript 不允许内联。RegexOption 成员
内联字符
说明
None
N/A
指定不设置任何选项。
IgnoreCase
i
指定不区分大小写的匹配。
Multiline
m
指定多行模式。更改 ^ 和 $ 的含义,以使它们分别与任何行的开头和结尾匹配,而不只是与整个字符串的开头和结尾匹配。
ExplicitCapture
n
指定唯一有效的捕获是显式命名或编号的 (?<name>…) 形式的组。这允许圆括号充当非捕获组,从而避免了由 (?:…) 导致的语法上的笨拙。
Compiled
N/A
指定正则表达式将被编译为程序集。生成该正则表达式的 Microsoft 中间语言 (MSIL) 代码;以较长的启动时间为代价,得到更快的执行速度。
Singleline
s
指定单行模式。更改句点字符 (.) 的含义,以使它与每个字符(而不是除 \n 之外的所有字符)匹配。
IgnorePatternWhitespace
x
指定从模式中排除非转义空白并启用数字符号 (#) 后面的注释。(有关转义空白字符的列表,请参见字符转义。) 请注意,空白永远不会从字符类中消除。
RightToLeft
N/A
指定搜索是从右向左而不是从左向右进行的。具有此选项的正则表达式将移动到起始位置的左边而不是右边。(因此,起始位置应指定为字符串的结尾而不是开头。) 为了避免构造具有无限循环的正则表达式的可能性,此选项不能在中流指定。但是,(?<) 回顾后发构造提供了可用作子表达式的类似替代物。RightToLeft 只更改搜索方向。它不会反转所搜索的子字符串。预测先行和回顾后发断言不改变:预测先行向右搜索;回顾后发向左搜索。
ECMAScript
N/A
指定已为表达式启用了符合 ECMAScript 的行为。此选项仅可与 IgnoreCase 和 Multiline 标志一起使用。将 ECMAScript 同任何其他标志一起使用将导致异常。
CultureInvariant
N/A
指定忽略语言中的区域性差异。有关更多信息,请参见在 RegularExpressions 命名空间中执行不区分区域性的操作。
if (m.Groups["key3"].Success)
{
string key3 = m.Groups["key3" ].Value.Trim();
string value3 = m.Groups["value3"].Value;
Console.WriteLine("Key3 = [{0}]", key3 );
Console.WriteLine("Value3 = [{0}]", value3);
}