简体   繁体   English

如何在两行之间选择文本

[英]How to select text between two lines

I have a text file like this 我有一个这样的文本文件

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

I need to get all the set of users from this text file. 我需要从此文本文件中获取所有用户。 one user data set should be like below. 一个用户数据集应如下所示。

[user]
name
age
sex

What is the regex I can uses for this purpose. 我可以用于此目的的正则表达式是什么。

Edit: Sometimes there are spaces between lines. 编辑:有时行之间有空格。 So no issue to have same line spaces in the result 因此在结果中具有相同的行间距没有问题

This is what is tried. 这是尝试。 but no luck 但没有运气

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

Once you've read the file (or part of it) to a string, you can use String.Split . 将文件(或文件的一部分)读取为字符串后,即可使用String.Split

something like this maybe: 可能是这样的:

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

This will give you a string ( result ) with each "block". 这将为您提供每个“ block”的字符串( result )。 Then use like split with newline as delimiter or something. 然后使用like split和换行符作为分隔符或其他东西。

Here is a simple, working, example: Demo 这是一个简单的示例: 演示

here is a regex to match the same 这是一个匹配相同的正则表达式

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

test string 测试字符串

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

result 结果

MATCH 1 比赛1

name [7-12] name1 名称[7-12] name1

age [13-17] age1 年龄[13-17] age1

sex [18-22] sex1 性别[18-22] sex1

MATCH 2 比赛2

name [30-35] name2 名称[30-35] name2

age [36-40] age2 年龄[36-40] age2

sex [41-45] sex2 性别[41-45] sex2

MATCH 3 比赛3

name [53-58] name3 名称[53-58] name3

age [59-63] age3 年龄[59-63] age3

sex [64-68] sex3 性别[64-68] sex3

try demo here 在这里尝试演示

Update 更新

regex updated to match gaps & optional spaces in lines if necessary 正则表达式已更新,以匹配行中的间隙和可选空格

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

try demo here 在这里尝试演示

Replace below line. 替换下面的行。 Each item in "content" will have lines from different user. “内容”中的每个项目都有来自不同用户的行。

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

You can accomplish this by using a 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);
        }
    }
}
(?ms)\G\[(?<user>.*?)\](?<params>[^\[]+)

组“ user”中的用户和组“ params”中的参数

Would it not be better to use a higher-level User class to hold each user's data? 使用更高级别的User类来保存每个用户的数据会更好吗?

Here's a basic example (with no error handling): 这是一个基本示例(无错误处理):

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;
            }
        }
    }
}

Please try this: 请尝试以下方法:

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

Regex explanation :) 正则表达式说明:)

/(?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! 查看正则表达式演示!

With this regex you will get the following two matches from the test case: 使用此正则表达式,您将从测试用例中获得以下两个匹配项:

 [user] name1 age1 sex1 [user] name2 age2 sex2 

And the best part is that you can change the two [user] sequence in your regex to whatever you like and it will still return the correct match: 最好的部分是,您可以将正则表达式中的两个[user]序列更改为所需的任何值,它仍将返回正确的匹配项:

x
(source: gyazo.com ) (来源: gyazo.com

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM