[英]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 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
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*))
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.
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]
序列更改为所需的任何值,它仍将返回正确的匹配项:
我建议将数据另存为json字符串,然后使用json库将其转换为对象或数组
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.