【问题标题】:Split Text With Multiple Delimiters使用多个分隔符拆分文本
【发布时间】:2016-03-02 08:59:48
【问题描述】:

需要建议。考虑以下带有文本段落的示例文件。

1
Lorem ipsum dolor sit amet, cum at doming urbanitas mnesarchum. Eum ad paulo inermis. Iuvaret minimum mnesarchum ad mei. Dolores placerat pro ex.

Vel zril facete utamur et. Id dicam fuisset contentiones mea, vidisse sapientem consequuntur his ex. Vivendum liberavisse ut usu, mel habeo postea disputationi id. 
Timeam aliquid nec no, ex duo option dolorum appareat. Ut tota interesset vim, ne graeci principes sea. Mel et postulant repudiare, eos an populo appareat, 
qui placerat iudicabit instructior at. Qui sint malis an.


1 
2
Ne mutat putant omnium eos, cu duo malis molestie reprehendunt. Te duo adhuc posse graecis, inermis mediocrem sed te. 
Eam cu latine eruditi electram, populo nemore suscipit vim ei, hinc reformidans voluptatibus pri te. Ut suas sanctus epicurei eam, 
legimus luptatum ei duo. No mel recteque scriptorem referrentur, ne mel duis cetero consequat, id possit offendit mel.
2
3

3
4

Eu usu tamquam docendi, eum at facer semper sententiae, veritus deserunt ei vis. Id albucius insolens mea, sea ad amet nibh. 
Sed id epicuri luptatum liberavisse, mei etiam scripta no. Quod detracto ei qui, imperdiet posidonium in eos. 
4
:
:
N
:
N

这里的分隔符是段落本身的序列号。

(即)

[Line Break]Number[Line Break]Passage[Line Break]Number[Line Break]

我可以通过哪些方法/方式更快地将这些段落拆分为单独的文件,而不是逐行迭代它们。

虽然我现在正在使用 C# 和 SQL,但我也听说 Phyton 在这些类型的操作中要快得多。所以我也可以尝试任何其他选项。

编辑: 为了清楚起见,我将它们作为文本段落作为示例。这些段落是其他模块的实际说明/输入。更清楚地说,这些段落将包含数字。

【问题讨论】:

    标签: c# text split logic


    【解决方案1】:

    这对于正则表达式来说是一项很好的工作。你可以这样做:

    Regex regex = new Regex(@"(\b[0-9]+\b)(.*?)(\1)",RegexOptions.Singleline);
    string s = ...
    var result = regex.Matches(s)
                      .Cast<Match>()
                      .Select(m => m.Groups[2].Value.Trim(Environment.NewLine.ToCharArray()))
                      .ToList();
    
    • (\b[0-9]+\b):匹配一个单词边界,然后匹配任何数字后跟一个单词边界(防止数字在文本中间匹配,在第一段添加“1 1 1”,结果保持不变)
    • (.*?):以非贪婪的方式匹配任何字符
    • (\1):匹配开头捕获的数字(为了安全起见,捕获在段落中的任何随机数处停止的可能性较小)

    Demo

    结果将获取第二组 (.*?) 捕获的字符串,并从开头和结尾修剪换行符。

    这将给出一个带有元素的List&lt;string&gt;

    result[0]:

    “Lorem ipsum dolor sit amet, cum at doming urbanitas mnesarchum. Eum ad paulo inermis. Iuvaret minimum mnesarchum ad mei. Dolores placerat pro ex.

    Vel zril facete utamur 等。 Id dicam fuisset contentiones mea, vidisse sapientem consequuntur 他的前任。 Vivendum liberavisse ut usu, mel habeo postea disputationi id。 Timeam aliquid nec no,ex duo option dolorum appareat。 Ut tota interesset vim, ne graeci principes sea。 Mel et postulant repudiare, eos an populo appareat, qui placerat iudicabit 讲师在。 Qui sint malis an。”

    result[1]:

    Ne mutat putant omnium eos,cu duo malis molestie reprehendunt。 Te duo adhuc posse graecis, inermis mediocrem sed te。 Eam cu latin eruditi electroram,populo nemore suscipit vim ei,hinc Reformidans voluptatibus pri te。 Ut suas sanctus epicurei eam, legimus luptatum ei duo。 No mel recteque scriptorem referrentur, ne mel duis cetero consequat, id possit offendit mel。

    等等……

    编辑:

    如果您想过滤掉空段落,您可以在选择后执行.Where(str =&gt; !String.IsNullOrEmpty(str))。那么你只会得到 3 个结果。

    【讨论】:

    • 感谢您的演示。对于大于 10 的序列(两位数或三位数),这个数字条件 ([0-9]+) 只满足一个问题。
    • @madmonk88 是的,+ 意味着匹配任何数字 0-9 至少一次并且尽可能多地匹配(所以直到遇到除数字之外的其他东西)
    • @madmonk88 对正则表达式进行了编辑,因此数字后面必须跟一个换行符。例如,如果我现在在第一段中添加1 1 1,我仍然会得到正确的结果。
    • 感谢您的回复。它仅对单个数字序列按预期精确工作。我还在调整它。
    • @madmonk88 对我来说它适用于任何数字,你确定你有正确的正则表达式吗?
    【解决方案2】:

    你是从文件还是数据库中读取这个?无论如何,如果这将存储在一个字符串中,那么您可以使用 split 方法:

    String.Split Method

    【讨论】:

    • 它来自 word 文档或 txt 文件,这些文件的大小会有所不同。我只需要序列号内的段落。使用 Split 进行迭代需要时间。我需要无论文本大小如何都能获得更快结果的方法。
    • 除非您的分隔符绝对不会包含在文本本身中,否则无论是拆分还是子字符串,甚至是 Regex.Split,您都会遇到问题。
    • 为了清楚起见,我将它们作为文本段落提供。这些段落是其他模块的实际说明/输入。更清楚地说,这些段落将包含数字。
    • 这就是为什么我说它不起作用。您的分隔符不是实际的分隔符。
    • 我向高层提出的相同论点,但文件来自旧平台。我坚持下去。 :(
    【解决方案3】:

    您可以使用Regex.Split 按模式进行拆分。如果段落中没有数字,可以使用“[0-9]+”。

    var passages = Regex.Split(text, "[0-9]+");
    

    【讨论】:

    • [0-9] 将是比\d 更安全的选择;如果有 超过 9 个块,您必须使用 [0-9]+\\d+
    • @DmitryBychenko 感谢您的提示。答案已编辑:)
    【解决方案4】:

    在 Python 中,你可以很容易地做到这一点:

    lines = filter(None, map(lambda l: l.strip(), open('text_file', mode='r').readlines()))
    map(lambda item: open(item[0], 'w').write(item[1]), [lines[i:i + 2] for i in range(0, len(lines), 2)])
    

    第一行将所有内容读取到一个字符串列表中,如下所示: ['1', '第 1 段文本', '2', '第 2 段文本', '3', '第 3 段文本', ...]

    第 2 行取列表中的每 2 个元素,并使用第一个元素作为文件索引,将第二个元素作为要写入文件的文本。

    希望这会有所帮助。

    【讨论】:

    • 尝试了你的代码,我的第一次 phyton 执行,除了没有其他消息之外,指向第二行的错误。同样在文件位置,我可以看到以序列名称命名的文件,但只有第一个带有文本拆分,其余为空。告诉我应该再添加什么。
    • 您能分享一下您遇到的错误吗?您还可以发送文件样本吗?我假设文件如下所示: 1 段落编号 1 段落编号 1 段落编号 1 2 段落编号 2 段落编号 2 段落编号 2 3 段落编号 3 段落编号 3 段落编号 3 4 段落编号 4 段落编号 4 段落编号 4 段落编号4 通道号 4 通道号 4 通道号 4 通道号 4 通道号 4
    • 我一步一步制作了下面的截图。我认为迭代存在错误,但我无法纠正它,因为我确信它的语法,对不起。 Step 1Step 2Step 3Step 4
    • 好的,我不确定我是否理解确切的格式。你有几个数字,后面没有任何段落。例如,数字“1”是重复的。数字“2”也是如此。 “3”是紧随其后的“4”的副本。我的问题是语法不是很连贯。我期待的是:数字,段落,数字,段落等等......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-27
    • 1970-01-01
    相关资源
    最近更新 更多