将文本分成块(Javascript,正则表达式)

4

我尝试使用Javascript和正则表达式将文本分成几个较小的块以进行解析。我在此处提供了最佳示例:

https://regex101.com/r/jfzTlr/1

我有一组规则需要遵循:我想要接收块。每个块都以星号(*)作为第一个符号(如果没有缩进,则为制表符),后跟2-3个大写字母、逗号、(可能的)空格和代码,可以是A、R、T、RS或RSS。随后是一个可选的句点。接下来是换行,在此之后是文本。该文本以下一个星号结束,遵循与上述相同的模式。

有人能帮我找出如何相应地拆分吗?这是我的模式:

[^\t](.{2,3}),\s?.{1,3}\.?\n.*

非常感谢!


这个链接对你有效吗? - Gurmanjot Singh
非常好,谢谢。与下面的其他答案非常相似,这个方法很有效,但是还有另一个答案可以让我在代码中进一步分组所需的项目。感谢您的努力! - chr_lt_ney
3个回答

1
你可以使用

标签。

^[ \t]*\*[A-Z]{2,3},\s*(?:[ART]|RSS?)\.?[\n\r](?:(?!^[ \t]*\*[A-Z]{2,3},\s*(?:[ART]|RSS?)\.?)[\s\S])+

请查看regex101.com上的演示


分解为以下几个部分:

^[ \t]*\*[A-Z]{2,3}           # start of the line, spaces or tabs and 2-3 UPPERCASE letters
,\s*(?:[ART]|RSS?)\.?[\n\r]   # comma, space (optional), code, dot and newline
(?:                           # non-capturing group

    (?!^[ \t]*\*[A-Z]{2,3},\s*(?:[ART]|RSS?)\.?)   
                              # neg. lookahead with the same pattern as above
    [\s\S]                    # \s + \S = effectively matching every character
)+

这项技术被称为温和贪婪的标记。

谢谢 - 几乎是需要的。关于代码和操作,它有点松散,我注意到它没有考虑代码后可能出现的点。我忘了提到分组是一个(非常)好的建议,但再次感谢您的努力! - chr_lt_ney
@chr_lt_ney:已更新,请查看新形成的演示和正则表达式(现在更紧凑)。 - Jan
哇,谢谢!正如我在上面的评论中提到的:工作做得很棒,但还有另一个答案可以让我在代码中进一步对所需项目进行分组。感谢你的努力! - chr_lt_ney

1

既然你要使用JavaScript,为什么不用split函数呢?它可以将分隔符和分隔后的部分都返回给你。然后把标题绑定在一个数组里,像这样:

[[heading1, block1], [heading2, block2], ...]

这样,您就可以立即获得以后继续处理的漂亮格式的数据。只是一个想法!

const s = `*GW, A
This is my very first line. The asterics defines a new block, followed by the initials (2-3 chars), a comma, a (possible) space and a code that could be A, R, T, RS or RSS. Followed by that is an optional dot. Linebreak afterwards, where the text comes.

 *JP, R.
 New block here, as the line (kind of) starts with an asterics. Indentations with 4 spaces or a tab means that it is a second level thing only, that does not need to be stripped away necessarily.

 But as you can see, a block can be devided into several
    lines, 

    even with multiple lines.

 *GML, T.
 And so we continue...

    Let's just make sure that a line can start with an
    *asterics, without breaking the whole thing.
 *GW, RS
 Yet another block here.

  *GW, RSS.
  And a very final one.

        Spread over several lines.

*TA, RS.
First level all of a sudden again.
*PA, RSX
    Just a line to check whether RSX is a separate block.

`;
  
const splits = s.split(/\*([A-Z]{2,3}),\s?([AT]|RS{0,2})(\.?)\n/).slice(1);

const grouped = [];

for (let i = 0; i < splits.length; i += 4) {
  const group = splits.slice(i, i+3);
  group[3] = splits[i+3].trim().split(/\s*[\r\n]+\s*/g);
  grouped.push(group);
}

console.log(grouped);


非常好,特别是因为我也需要找到这些组。你能看一下几件事吗?我尝试过了,但无法完全使其工作:a)确保有效代码列表确实起作用(A、R、T、RS或RSS)。现在例如RSX有效,但它是无效的。 b)捕获可能的点(在代码之后,在换行符之前)。 c)是否可能将块中的所有行都作为它们自己捕获?因此,一个块将包括缩写、代码、可能的点和在下一个星号出现之前跟随的行数组。 - chr_lt_ney
看到我的编辑。我无法验证RSX是否会导致一个单独的块。我在文本底部添加了*PA,RSX,但它并没有导致新的块。我还修剪了行中文本前后的空格字符。如果您不想要这个,请去掉trim() - Bram Vanroy
1
没问题。祝你好运,编码愉快! - Bram Vanroy

-1

希望这是你想要的。这个可以工作。

([\*\t])+(.{2,3}),\s?.[A,R,T,RS,RSS]{1,3}\.?\n.*


很遗憾,我无法让它按照我的预期运行。请尝试在上面使用我的regex101链接并粘贴您的代码。它没有像预期的那样处理整个块。 - chr_lt_ney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接