我无法理解如何在 c# 中使用正则表达式或如何解决我的问题
Posted
技术标签:
【中文标题】我无法理解如何在 c# 中使用正则表达式或如何解决我的问题【英文标题】:I cannot wrap my head around on how to use regex in c# or how to solve my problem otherwise 【发布时间】:2020-10-27 20:36:24 【问题描述】:我有以下问题:我无法分别从 Winforms 中的另一个文本框中提取特定字符串 C#:
在 TextboxA 中显示以下字符串(它是多行的。每个“”都是一行):
" OUT01: Valid __GO__ 103,2"
" OUT02: Valid __GO__ -0,54"
" OUT03: Valid __GO__ 0,25"
" OUT04: Valid ____LO 46,41"
在 Textbox1 中只需要显示“103,2”。在 Textbox2 中“-0,54”,在 Textbox3 中“0,25”和在 Textbox4 中分别为“46,41”。 我的 C# 项目的命名空间不允许浮点或双精度值。因此,在文本框 1-4 中必须有字符串值。因此 float.Parse(stringTextboxA);方法不起作用。用正则表达式怎么解决?
我已经试过了:
const string MeasurementValue1 = " OUT01: Valid __GO__ ";
var match = Regex.Match(MeasurementValue1, " OUT01: Valid __GO__ (*)");
txb_Textbox1.Text = match;
但这不起作用。一些更有经验的 C# 程序员和“正则表达式”专家可以告诉我一些问题吗?提前致谢!
最好的问候
【问题讨论】:
var match = Regex.Match(MeasurementValue1, @"OUT01:\s+Valid\s+__GO__\s+(\d+)")?.Groups[1].Value;
?
我不会为此使用正则表达式。我只是将文本拆分为换行符,然后在每一行中搜索第一个空格,从右侧开始并在左侧工作。然后根据该字符位置拉出子字符串。
或匹配所有十进制值OUT\d+: Valid (?:__GO__|____LO) (-?\d+(?:,\d+)?)
regex101.com/r/ehqu1V/1
在你已经尝试过的代码中,你试图匹配一个没有任何实际数字的字符串,所以无论你得到什么匹配都是空的。你也不能只匹配*
- 你的意思是.*
匹配任何字符。
如果您的字段与示例中显示的一样恒定,那么从位置 27 开始的简单子字符串可能会做吗?否则我喜欢@BradleyUffner 的解决方案。
【参考方案1】:
*
本身就是一个量词。如果你在https://regex101.com/r/IYOlyB/1 上检查这个,你可以看到使用(*)
,红色星号表示前面的标记是不可量化的。
您可以将其设为(.*)
,但点匹配任何字符并且是十进制值的广泛匹配。
获取值的一个选项可能是使用例如量词\s2,
来确定空格数。
要匹配 GO 和 LO 变体中的任何一个,您可以使用替换 |
来匹配其中任何一个。
十进制值可以在组1中捕获。
^\s+OUT\d+: Valid\s2,(?:__GO__|____LO)\s2,(-?\d+(?:,\d+)?)$
说明
^
字符串开始
\s+OUT\d+: Valid
匹配字符串的开头,使用\d+
匹配1+位数
\s2,
匹配 2 个或更多空白字符
(?:
交替的非捕获组|
__GO__
字面匹配
|
或者
____LO
字面也匹配
)
关闭非捕获组
\s2,
匹配 2 个或更多空白字符
(-?\d+(?:,\d+)?)
捕获组 1,匹配可选的 -
,1+ 位和可选的小数部分
$
字符串结束
.NET regex demo
【讨论】:
根据正则表达式演示,这似乎效果最好。不幸的是,我不能使用索引运算符,因为我的项目是用 C# 7.3 版编写的,而索引运算符至少需要 C# 8.0 版。我无法更改构建的 C# 版本,因为语言版本基于我的项目的框架版本......啊,当然:你是对的! * 本身只是一个量词。我忘记了“。”在“(.*)”中。 @s950mpc2000 如果您只想要匹配项,您可以使用积极的后向观察(?<=^\s+OUT\d+: Valid\s2,(?:__GO__|____LO)\s2,)-?\d+(?:,\d+)?$
见demo
我用你的正则表达式写了以下代码string pattern = @"(?<=^\s+OUT\d+: Valid\s2,(?:__GO__|____LO)\s2,)-?\d+(?:,\d+)?\r?$"; string input = strLog; RegexOptions options = RegexOptions.Multiline; foreach (Match m in Regex.Matches(input, pattern, options)) Console.WriteLine("'0' found at index 1.", m.Value, m.Index);
。有用。它使用适当的索引在控制台中显示 4 个浮点值。如何在 4 个不同的文本框中插入这些值?所以第一个值 textbox1,第二个 textbox2 等等..
@s950mpc2000 如果这是设置值txb_Textbox1.Text =
并且值在m.Value
中的方法,则一种选择是通过索引从MatchCollection 获取值并分配m.Value
到.Text
属性。或者您可以使用索引循环集合,如果文本框是树结构中的子级,则获取父级的第 n 个子级。
我做了一个工作,因此找到了我的问题的解决方案。例如对于第二个值,它出现在 OUT02 之后我首先使用了以下正则表达式 @"^\s+(?:OUT02): Valid\s2,(?:__GO__|____LO)\s2,(-?\d+(?:,\d+)?)$";
,然后我删除了我不需要的字符串 string.Remove(0, 23);
非常感谢您的所有输入和回答! :)【参考方案2】:
尝试以下:
public Form1()
InitializeComponent();
textBox5.Multiline = true;
textBox5.Text =
" OUT01: Valid __GO__ 103,2\r\n" +
" OUT02: Valid __GO__ -0,54\r\n" +
" OUT03: Valid __GO__ 0,25\r\n" +
" OUT04: Valid ____LO 46,41\r\n";
List<TextBox> boxes = new List<TextBox>() textBox1, textBox2, textBox3, textBox4 ;
string pattern = @"[\d,\-\+]+\r\n";
MatchCollection matches = Regex.Matches(textBox5.Text, pattern);
string[] values = matches.Cast<Match>().Select(x => x.Value.Trim()).ToArray();
for (int i = 0; i < values.Length; i++ )
boxes[i].Text = values[i];
【讨论】:
【参考方案3】:可以在这里扩展我的评论是您的数据在解析时的样子:
string myText = @""" OUT01: Valid __GO__ 103,2""
"" OUT02: Valid __GO__ -0,54""
"" OUT03: Valid __GO__ 0,25""
"" OUT04: Valid ____LO 46,41""";
int[] colsizes = @""" OUT01: Valid ".Length, "__GO__ ".Length, 20;
var myData = myText.Split('\n').Select(x => new
column1 = x.Substring(0, colsizes[0]).Trim(' ', '"'),
column2 = x.Substring(colsizes[0], colsizes[1]).Trim(),
column3 = decimal.TryParse(
x.Substring(colsizes[0]+colsizes[1]).Trim().Replace("\"",""),
NumberStyles.Any, new CultureInfo("tr-TR"), out decimal result)
? result : 0M
);
foreach (var d in myData)
Console.WriteLine($"Column1: [d.column1], Column2: [d.column2], Column3: [d.column3]");
Form f = new Form();
DataGridView dgv = new DataGridView Dock=DockStyle.Fill, DataSource=myData.ToList();
f.Controls.Add(dgv);
f.Show();
PS:要显示数据,请尝试使用 DataGridView 代替文本框。你有数据行。 已编辑以显示在 DataGridView 中。
【讨论】:
【参考方案4】:在您提供的 4 个字符串示例中,此正则表达式将仅匹配您指出需要包含的数字:
"\s[-0-9]1,,[0-9]1,2"
它查找空格“\s”,然后是 1 个或多个“1,”字符等于“-”或“0-9”,然后它必须找到一个逗号,然后正好是 1 个或 2 个“ 1,2" 数字 "0-9"。
你会像这样使用它:
var match = Regex.Match(" OUT04: Valid ____LO 46,41", "\s[-0-9]1,,[0-9]1,2");
在这种情况下,匹配应该等于“46,41”。
试一试。你可以像我在这里一样测试你的正则表达式:https://www.regexpal.com/
【讨论】:
【参考方案5】:您可以在没有正则表达式的情况下执行此操作,以满足您的要求,将文本按新行拆分,然后将行的最后一个值用空格拆分。我希望您的 c# 项目的命名空间不会强迫您使用正则表达式。 ;)
textboxA.Text = @"
OUT01: Valid __GO__ 103,2
OUT02: Valid __GO__ -0,54
OUT03: Valid __GO__ 0,25
OUT04: Valid ____LO 46,41
";
var withoutEmptyValues = StringSplitOptions.RemoveEmptyEntries;
var values = textboxA.Text
.Split(new[] Environment.NewLine , withoutEmptyValues)
.Select(line => line.Split(new[] " " , withoutEmptyValues).Last())
.ToArray();
textBox1.Text = values[0];
textBox2.Text = values[1];
textBox3.Text = values[2];
textBox4.Text = values[3];
我建议使用更合适的控件来显示集合,例如列表框或数据网格视图或多行文本框。
【讨论】:
以上是关于我无法理解如何在 c# 中使用正则表达式或如何解决我的问题的主要内容,如果未能解决你的问题,请参考以下文章
何时不在 C#(或 Java、C++ 等)中使用 Regex
如何在 C# 2.0 中使用正则表达式处理 < 或 > 类型的字符串的编码
如何使用正则表达式(或 C# 函数)在一个变量中剪切 TEXT MESSAGE 并从此文本中剪切第二个变量 USERNAME?
如何使用 C# 在 Visual Studio 2010 中使用正则表达式或 HTMLAgilityPack 抓取 HTML 页面的特定部分?