如何在两行之间选择文本

时间:2014-08-07 07:42:17

标签: c# regex

我有一个像这样的文本文件

[user]
name
age
sex
[user]
name
age
sex
[user]
name
age
sex

我需要从此文本文件中获取所有用户集。一个用户数据集应如下所示。

[user]
name
age
sex

我可以用于此目的的正则表达式是什么。

修改:有时行之间会有空格。因此,在结果中使用相同的行空格没有问题

这是尝试过的。但没有运气

string content = File.ReadAllText(file);
MatchCollection matches = Regex.Matches(content, @"/(?m)[user].*?[user]/");

8 个答案:

答案 0 :(得分:4)

一旦您将文件(或部分文件)读取为字符串,即可使用String.Split

这样的事情可能是:

String[] result;
result = yourString.Split(new string[] {"[user]"}, StringSplitOptions.RemoveEmptyEntries);

这将为每个"块"提供一个字符串(result)。然后使用like new with newline作为分隔符或其他东西。

这是一个简单,有效的示例:Demo

答案 1 :(得分:1)

这是匹配相同

的正则表达式
(?:\[user\]\n(?'name'.*)\n(?'age'.*)\n(?'sex'.*))

测试字符串

[user]
name1
age1
sex1
[user]
name2
age2
sex2
[user]
name3
age3
sex3

<强>结果

MATCH 1

姓名[7-12] name1

年龄[13-17] age1

性[18-22] sex1

MATCH 2

姓名[30-35] name2

年龄[36-40] age2

性[41-45] sex2

MATCH 3

姓名[53-58] name3

年龄[59-63] age3

性[64-68] sex3

尝试demo here

<强>更新

正则表达式更新以匹配差距&amp;必要时行中的可选空格

(?:\[user\][\n\s]*(?'name'\w*)[\n\s]*(?'age'\w*)[\n\s]*(?'sex'\w*))

尝试demo here

答案 2 :(得分:0)

替换下面的行。 &#34;内容&#34;中的每个项目将有来自不同用户的行。

string[] content = File.ReadAllText(file).Split(new string[] {"[user]"},StringSplitOptions.RemoveEmptyEntries);

答案 3 :(得分:0)

您可以使用streamreader

来完成此操作
List<List<string>()> users;
using (StreamReader reader = new StreamReader("file.txt"))
{
    string line;
    List<string> currentUser;
    while((line = reader.readLine()) != null)
    {
        if(line == "[user]")
        {
            if(currentUser != null)
                 users.Add(currentUser);
            currentUser = new List<string>{line};
        }
        else
        {
            currentUser.Add(line);
        }
    }
}

答案 4 :(得分:0)

(?ms)\G\[(?<user>.*?)\](?<params>[^\[]+)

用户分组&#34;用户&#34;和组中的参数&#34; params&#34;

答案 5 :(得分:0)

使用更高级别的User课程来保存每个用户的数据会不会更好?

这是一个基本示例(没有错误处理):

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Demo
{
    sealed class User
    {
        public string Name; // Real code should make these properties.
        public string Age;
        public string Sex;

        public override string ToString()
        {
            return string.Format("Name: {0}, Age: {1}, Sex: {2}", Name, Age, Sex);
        }
    }

    internal static class Program
    {
        static void Main(string[] args)
        {
            string[] source =
            {
                "[user]",
                "name1",
                "age1",
                "sex1",
                "",
                "[user]",
                "",
                "name2",
                "age2",
                "sex2",
                "",
                "[user]",
                "name3",
                "age3",
                "sex3",
                "",
                "",
                "This should be ignored",
                "So should this",
                "[user]",
                "name4",
                "age4",
                "sex4"
            };

            var nonblankLines = source.Where(x => !string.IsNullOrWhiteSpace(x));

            // If reading from a file, use this instead:
            // var nonBlankLines = File.ReadLines(filename).Where(x => !string.IsNullOrWhiteSpace(x));

            var users = readUsers(nonblankLines.GetEnumerator());

            Console.WriteLine(string.Join("\n", users)); // Print them out.

            // If for some reason you need a list of users rather than an Enumerable<User>, do this:

            // var listOfUsers = users.ToList();
        }

        static IEnumerable<User> readUsers(IEnumerator<string> input)
        {
            while (true)
            {
                while (input.Current != "[user]")
                    if (!input.MoveNext())
                        yield break;

                input.MoveNext();

                User user = new User();
                user.Name = input.Current;
                input.MoveNext();
                user.Age = input.Current;
                input.MoveNext();
                user.Sex = input.Current;

                yield return user;

                if (!input.MoveNext())
                    yield break;
            }
        }
    }
}

答案 6 :(得分:0)

请试试这个:

string content = File.ReadAllText(file);
MatchCollection matches = Regex.Matches(content, @"/\[user\].*?(?=\[user\])/s");

正则表达式解释:)

/(?x)       # extended
 \[user\]   # Literal character sequence "[user]"
 .*?        # Any number of anything, newline included (s modifier)
 (?=        # Open positive lookahead group: Asserts match ahead
   \[user\] # Literal character sequence "[user]"
 )          # Closes group.
/s    // s modifier: dot matches new lines.

View a regex demo!

使用此正则表达式,您将从测试用例中获得以下两个匹配项:

[user]
name1
age1
sex1

[user]
name2
age2
sex2

最好的部分是,您可以将正则表达式中的两个[user]序列更改为您喜欢的任何内容,它仍会返回正确的匹配项:

x http://gyazo.com/22c6491848efa6bea5f37bbf14769224.png

答案 7 :(得分:-1)

我建议将数据保存为json字符串,然后使用json库将其转换为对象或数组