【问题标题】:Get every item from markdown list under headings从标题下的降价列表中获取每个项目
【发布时间】:2021-01-06 01:42:13
【问题描述】:

这里是示例降价文件

# Test

## First List

* Hello World
* Lorem
* foo

## Second List

- item

## Third List

+ item 1
part of item 1
+ item 2

## Not a List

bla bla bla

## Empty

## Another List

bla bla bla



bla

* ITEM

## Nested List

### Inside Nested

* foo
* bar

到目前为止我有这个代码:

const markdown = await fs.promises.readFile(path.join(__dirname, 'test.md'), 'utf8');
const regexp = /^#{1,6} (.*)[.\n]*[*\-+] (.*)/gm;
const result = markdown.matchAll(regexp);
console.log([...result].map(m => m.slice(1)));
[
  [ 'First List', 'Hello World' ],
  [ 'Second List', 'item' ],
  [ 'Third List', 'item 1' ],
  [ 'Inside Nested', 'foo' ]
]

第一个问题是它只抓取第一个项目,第二个是如果项目是多行它只会抓取第一行,最后它不包括Another List,因为标题和列表之间有文本。

我对正则表达式很陌生,不确定我当前的正则表达式是否可以安全使用。

所以基本上我想找到markdown文件中的每个列表把它放在一个数组中然后看看上面是否有一个标题而不是另一个某种列表然后把那个标题放在那个数组的开头(所有人都认为不必一定是那种格式,也可以是对象,我只是认为数组会更简单)

想要的结果:

[
  ['First List', 'Hello World', 'Lorem', 'foo'],
  ['Second List', 'item'],
  ['Third List', 'item 1\npart of item 1', 'item 2'],
  ['Another List', 'ITEM'],
  ['Inside Nested', 'foo', 'bar']
]

【问题讨论】:

  • 正则表达式对此并不好。您可以执行第二个正则表达式来拆分/解析列表值。或者你可以做一些硬编码到固定数量的贫民区条件组。

标签: javascript node.js regex typescript markdown


【解决方案1】:

你可以试试这个正则表达式:

/(?<=#{1,6} (.*)\n(?:(?!#).*\n)*)(?=[+*-] (.*(?:\n(?![#+*-]).+)?))/g

基本上它匹配所有宽度为 0 的字符,并测试它前面是否有列表项(例如 * item)和前面是否有任何标题(例如 # Title),并将它们放在不同的组中。它们之间的任何内容都无关紧要,除非是另一个标题。

你可以see the test cases here

matchAll 结果将是

[
    ["", "First List", "Hello World"],
    ["", "First List", "Lorem"],
    ["", "First List", "foo"],
    ["", "Second List", "item"],
    ["", "Third List", "item 1\npart of item 1"],
    ["", "Third List", "item 2"],
    ["", "Another List", "ITEM"],
    ["", "Inside Nested", "foo"],
    ["", "Inside Nested", "bar"]
]

由于您无法创建具有动态数量匹配组的正则表达式,因此您需要手动将它们组合在一起。

这是完整的例子:

const markdown = `
# Test

## First List

* Hello World
* Lorem
* foo

## Second List

- item

## Third List

+ item 1
part of item 1
+ item 2

## Not a List

bla bla bla

## Empty

## Another List

bla bla bla



bla

* ITEM

## Nested List

### Inside Nested

* foo
* bar
`;

const regexp = /(?<=#{1,6} (.*)\n(?:(?!#).*\n)*)(?=[+*-] (.*(?:\n(?![#+*-]).+)?))/g;
const matches = [...markdown.matchAll(regexp)];
const result = matches.reduce((acc, cur) => {
    const [title, item] = cur.slice(1);
    const target = acc.find(e => e[0] === title);
    if(target) {
        target.push(item);
    } else {
        acc.push([title, item]);
    }
    return acc;
}, []);
console.log(result);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-01
    • 2020-04-26
    • 1970-01-01
    • 2021-04-02
    • 2021-05-20
    • 2013-06-11
    • 1970-01-01
    • 2012-12-30
    相关资源
    最近更新 更多