【问题标题】:C# Substring Alternative - Return rest of line within string after characterC# Substring Alternative - 在字符后返回字符串中的其余行
【发布时间】:2016-02-06 22:28:49
【问题描述】:

我有一些代码可以读取文本文件并将其设置为字符串。文本文件的每一行都包含我试图提取的单独数据参数。下面是一个字符串/文本文件布局的小例子:

...
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"

【问题讨论】:

  • string.Split() on =
  • Substring 有一个重载方法,可以返回字符串的其余部分。可以换成partData.Substring(strStart)查看文档msdn.microsoft.com/en-us/library/…
  • 您的编辑是不公平的,因为在您收到几个解决原始问题的答案后,它会彻底改变问题的要求。如果您现在有一个具有不同要求的不同问题,请发布一个新问题并在那里提问。您最初的问题没有询问提取多个值 - 它询问了一种更简洁的方法来获取等号右侧的部分,这是我们几个人的回答。
  • 我觉得我没有改变问题。我从一开始就说明文本文件被读取为给定格式的字符串。给定的格式包含几行。我唯一更改的是为行赋予唯一值,以便更容易理解我是如何提取单独数据的。
  • 我同意@SincereApathy - 这个问题确实包括编辑前的所有相关部分。在我看来,好像有些用户只是略过问题而不是实际阅读细节,然后就下结论了。

标签: c# substring


【解决方案1】:

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

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

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

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

【讨论】:

  • 这将返回字符串中第一个“=”之后的所有内容。我只想返回以“part=”或“weight=”或“quantity=”开头的行的其余部分(我只是以“part=”为例,因为我认为我可以从那里得到其他变量。)所以,我正在寻找的可能不在字符串中的第一个“=”之后,我不希望它从它所在的行下方的行返回任何内容。
  • 您发布(并用作示例)的字符串是part=XYZ,我发布的代码返回XYZ(这是您要求它执行的操作)。如果您的要求与您所说的不同,或者文件与您所包含的不同,请编辑您的问题,以便正确说明您要解决的问题。我的代码回答了您在发布答案时提出的问题。您现在是说您显示为单独行的所有内容实际上都在一行上吗?因为这不是您的问题所说的,即使在您编辑之后也是如此。
  • @KenWhite 图片太多了... ;)
  • @Lucero:本网站的工作方式是回答提出的问题,而不是您想象的发帖人将来可能想做的问题。我(和其他人)回答了所提出的问题。在人们发布原始问题的答案之后,我很想回滚更改要求的不当编辑。
  • 我正在使用StreamReader(textfile) 读取文本文件并将其分配给字符串。所以,string partData = reader.ReadToEnd();。数据在文本文件的不同行上,如果我执行MessageBox.Show(partData),它会在消息框中的不同行上显示它。如果我误解了它的工作原理,我深表歉意,实际上它不是在字符串变量中的单独行上。
【解决方案2】:

您也可以使用正则表达式来执行此操作;它可以处理比简单的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 确实显示了此代码如何处理您的示例数据。

【讨论】:

  • 呃。 我有一个简单的 Substring 问题。 你会回答 让我们通过在混合中引入一个完全不必要的正则表达式来让它变得更糟。 这相当于告诉用户询问如何将两个整数值相加转换为浮点数,执行计算,转换为字符串并使用 Substring 去除小数点,然后再转换回整数。
  • @KenWhite 我正试图退后一步,看看这张照片。 OP 明确指出他正在尝试从文本文件的行中提取数据,而这正是正则表达式解决方案可能确实是更好的方法的地方。我确实从一开始就写道,正则表达式不是简单案例的理想选择 - 但我尝试展示实现手头任务的选项。
  • 废话。任何类型的模式都没有复杂性。它是由“=”分隔的两个值。正则表达式的开销是不必要的。看图片和你在这里做的事情是有区别的。正则表达式有它们的位置,但这绝对不是其中之一。 (请注意,我没有投反对票;虽然我认为您的回答绝对是错误的方法,但技术上它会起作用。这太过分了,但它会起作用。)
  • @KenWhite 很公平,我尊重你的意见,但我不同意(我也没有投反对票;))。我每天都在研究解析器、状态机和有限自动机,所以我可能比普通用户更喜欢正则表达式,但这些“简单”模式通常会通过字符串修剪、有效性检查、识别其他模式来扩展线条等,这就是混乱开始恕我直言的地方。
  • @Lucero 我喜欢它的工作原理。每个文件可以包含可变数量的参数,这允许我只获取文件中的参数,而无需编写 IF 语句来检查所有可能的参数是否存在,如果存在则提取。一个问题。如何使用 for 循环将所有“值”分配给分隔字符串“键”,以便我可以在后续代码的循环之外使用它们? (也许这需要另一个问题)
【解决方案3】:

假设文本文件采用发布的格式并且包含数据参数,另一种方法是读取文件的内容并将内容投影到字典中,因为您已经知道参数名称,即。 “部分”、“数量”等……

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"];

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

【讨论】:

    【解决方案4】:

    你可以使用split,这样会更容易阅读:

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

    请注意,如果行中没有“=”,可能会引发异常。

    【讨论】:

      【解决方案5】:

      如果你使用这将更加健壮

      var parts = string.Split('=')
      

      谁知道是否有人决定在等号之前或之后放置一个空格?这会破坏您现有的解决方案,因为它找不到“part =XXX”。通过拆分,您可以获得两侧的零件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-03-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-01-10
        • 2017-01-02
        • 2015-07-27
        • 2015-09-16
        相关资源
        最近更新 更多