2016-02-06 55 views
0

我有一些代码读取文本文件并将其设置为字符串。文本文件的每一行都包含我尝试提取的单独数据参数。这里是字符串/文本文件是如何布局的小例子:C#子字符串替代方法 - 返回字符后字符串的其余部分

... 
part=XYZ 
quantity=123 
weight=14 
length=60 
... 

有没有在给定的行返回“=”之后的所有的好办法?

我目前得到它使用子字符串,但我很好奇,如果有一个更简洁的方式来获得相同的结果。这是我目前拥有的代码:

strStart = partData.IndexOf("part=") + 5; 
    strEnd = partData.IndexOf(" ", strStart); 
    string partNum = partData.Substring(strStart, strEnd - strStart); 

进一步澄清

我会从文本文件中提取多个变量。例如,给定上述数据我将提取4个变量:

partNum = “XYZ”

数量= “123”

wght = “14”

LEN = “60”

+4

'string.Split()''上='' – jdphenix

+1

具有Substring'一个重载方法,该方法返回字符串的其余部分。它可以用'partData.Substring(strStart)来代替'检查文档https://msdn.microsoft.com/en-us/library/system.string.substring(v=vs.110).aspx –

+0

你的编辑是不公平的,因为它在收到几个解决原始问题的答案后彻底改变了问题的要求。如果您现在有不同要求的问题,请发布一个新问题并在此处提问。你原来的问题并没有提出提取多个值的问题 - 它询问了一个更简洁的方法来让等号右边的部分,这是我们几个人的回答。 –

回答

1

您可以使用分裂,它可以更容易阅读:

string value = partData.Split('=', 2)[1]; 

谨防日如果线上没有'=',可以抛出异常。

4

是的,你可以做得更简洁。

string partNum = partData.Substring(partData.IndexOf("=") + 1); 

这使用的String.Substring重载的版本只接受一个参数,该串中的起始位置。它从这一点继续到字符串的末尾。

显然这只有在您确定partData中有等号时才有效,但您发布的原始代码也是如此。

+0

这会在字符串中的第一个“=”之后返回EVERYTHING。我只想返回以“part =”或“weight =”或“quantity =”开头的行的其余部分(我仅以“part =”为例,因为我认为我可以从那里拿到它)所以,我正在寻找的可能不是在字符串中的第一个“=”后面,我不希望它从它所在的行下面的行中返回任何东西。 – SincereApathy

+1

您发布的字符串(用作示例)是'part = XYZ',并且我发布的代码返回'XYZ'(这就是您要求它执行的操作)。如果您的要求与您所说的不同,或者文件与您所包含的文件不同,请编辑您的问题,以便正确说明您尝试解决的问题。我的代码回答了我在发布答案时提出的问题。你现在是否说过,你以单独的行显示的所有内容实际上都在同一行上?因为这是**而不是**你的问题所说的,甚至在你编辑之后。 –

+0

@KenWhite这么多的图片...;) – Lucero

0

这将是,如果你使用更强大的

var parts = string.Split('=') 

谁知道,如果有人决定等号之前或之后把一个空间?那会破坏你现有的解决方案,因为它找不到“part = XXX”。通过拆分,您可以在任一侧获得零件。

3

你也可以使用正则表达式来做到这一点;它可以处理比简单的IndexOfSplit解决方案更复杂的情况,例如跳过围绕=的空格或不匹配某些模式,或者一次提取单行中找到的所有组件。

string partNum = Regex.Match(partData, @"=(.*)$", RegexOptions.Multiline).Groups[1].Value; 

正则表达式将是简单的情况下,速度较慢(如在=只是分裂),但如果你真的想处理,并从中途复杂的模式会更有效,更简洁的提取数据好。

此外,通过检查匹配的Success属性,您可以验证数据符合预期模式,而不需要任何额外的处理/验证逻辑。

下面是其前后=之后签署其使用该串中的预期图案中的每个文本行提取部分的示例,并且修剪部件沿途:

for (Match match = Regex.Match(partData, @"^\s*([^=]+?)\s*=\s*(.*?)\s*$", RegexOptions.Multiline); 
     match.Success; 
     match = match.NextMatch()) { 
    // this code runs for each line in your string which has the expected pattern 
    string key = match.Groups[1].Value; 
    string value = match.Groups[2].Value; 
} 

编辑:Here's a fiddle它确实显示了这段代码如何处理您的示例数据。

+1

呃。*我有一个简单的子串问题*你对此作出回应*通过在混合中引入一个完全不必要的常规expressino,让它变得更糟糕*这相当于告诉用户如何添加两个整数值来转换它们到浮点数,执行计算,将其转换为字符串并使用Substring删除小数点,然后将其转换回整数。 –

+0

@KenWhite我想退后一步,看看图片。 OP明确指出他正试图从文本文件的行中提取数据,这正是正则表达式解决方案确实可能更好的方法。我从一开始就写过正则表达式并不是简单案例的理想选择 - 但我试图展示如何实现手头的任务。 – Lucero

+1

废话。没有任何复杂的模式。这是由'='分隔的两个值。正则表达式的开销是不必要的。看图片和你在这里做什么是有区别的。正则表达式有它们的位置,但这绝对不是其中之一。 (注意,我并没有低调;但我认为你的回答绝对是错误的方法,*在技术上*它会工作,这是巨大的矫枉过正,但它会*工作*。) –

2

假设文本文件格式发布和包含数据参数,另一种方法是读取文件的内容和项目内容为一本字典,因为你已经知道了参数的名称,即。 “部分”,“量”,等等

Dictionary<string, string> param = File 
    .ReadLines("path.to.file.txt") 
    .Select(x => x.Split('=')) 
    .ToDictionary(x => x[0], y => y[1]); 

内容然后可以通过键名访问,类似于你最初是如何分配的变量:

string partNum = param["part"]; 

或者,只是根据需要使用字典而不分配给局部变量。

相关问题