XRegexP.matchRecursive - 添加回调功能以允许多个相同的实例
XRegexP.matchRecursive - add callback functionality to allow for multiple identical instances
我正在使用 XRegexP 来解析一个文本文件,专门用于查找两组预定义评论标签之间的内容,我无法更改这些标签,因此我需要找到一种方法使其与提供的文本。
我使用提供的正则表达式找到了所有标签的列表(link 中的示例还包括示例内容):https://regex101.com/r/kCwyok/1/
然后我使用 XRegexP 的 matchRecursive
函数来获取开始和结束标签之间的所有内容,这些内容几乎都可以正常工作。
// Map the list of component tags and extract data from them
return generateComponentList(data).map((component) => {
console.log(chalk.blue('Processing', component[1], 'component.'))
const contents = XRegExp.matchRecursive(data, '<!-- @\[' + component[1] + '\][.\w-_+]* -->', '<!-- @\[/' + component[1] + '\] -->', 'g')
let body = ''
let classes = ''
contents.map((content) => {
const filteredContent = filterContent(content)
body = filteredContent.value
classes = cleanClasses(component[2])
console.log(chalk.green(component[1], 'processing complete.'))
})
// Output the content as a JSON object
return {
componentName: component[1],
classes,
body
}
})
我遇到的问题是CodeExample
标签存在两次,标签是一样的但是内容不一样,但是因为matchRecursive
好像没有回调函数,所以只是同时在该组件的所有实例上运行匹配,因此有 1 个或 10 个 CodeExample
实例并不重要,所有这些实例的内容都会返回。
有没有办法可以实际向 matchRecursive 添加某种回调?如果失败了,有没有办法让 JavaScript 了解正在查看哪个 CodeExample 实例,以便我可以直接引用数组位置?我假设 XRegexP 知道它正在查看哪个编号的 CodeExample 标记,那么有没有办法捕获它?
为了清楚起见,这里是完整的代码:https://pastebin.com/2MpdvdNA
我想要的输出是一个包含以下数据的 JSON 文件:
[
{
componentName: "hero",
classes: "",
body: "# Creating new contexts"
},
{
componentName: "CodeExample",
classes: "",
body: "## Usage example
```javascript
Import { ICON_NAME } from 'Icons'
```"
},
{
componentName: "ArticleSection",
classes: "",
body: // This section is massive and not relevant to question so skipping
},
{
componentName: "NoteBlock",
classes: ["warning"],
body: "> #### Be Careful
> Eu laboris eiusmod ut exercitation minim laboris ipsum magna consectetur est [commodo](/nope)."
},
{
componentName: "CodeExample",
classes: "",
body: "#### Code example
```javascript
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
```"
}
// Skipping the rest as not relevant to question
]
抱歉,如果我没有解释清楚,我已经看这个太久了。
最后是这样解决的:
import XRegExp from 'xregexp'
const extractComponents = data => {
const components = []
const re = '<!-- @\[(\w+)\]([.\w-_+]+)* -->'
XRegExp.forEach(data, XRegExp(re, 'g'), match => {
const name = match[1]
const classes = match[2]
const count = components.filter(item => item.name === name).length
const instance = count ? count : 0
components.push({
name,
classes,
instance
})
})
return components
}
const cleanClasses = classes => {
const filteredClasses = classes ? classes.split('.') : []
filteredClasses.shift()
return filteredClasses
}
const extractContent = (data, component) => {
const re = `<!-- @\[${component.name}\][.\w-_+]* -->`
const re2 = `<!-- @\[/${component.name}\] -->`
return XRegExp.matchRecursive(
data,
re, re2, 'g'
)[component.instance]
}
const parseComponents = data => {
return extractComponents(data).map(component => {
return {
componentName: component.name,
classes: cleanClasses(component.classes),
body: extractContent(data, component)
}
})
}
export default parseComponents
我正在使用 XRegexP 来解析一个文本文件,专门用于查找两组预定义评论标签之间的内容,我无法更改这些标签,因此我需要找到一种方法使其与提供的文本。
我使用提供的正则表达式找到了所有标签的列表(link 中的示例还包括示例内容):https://regex101.com/r/kCwyok/1/
然后我使用 XRegexP 的 matchRecursive
函数来获取开始和结束标签之间的所有内容,这些内容几乎都可以正常工作。
// Map the list of component tags and extract data from them
return generateComponentList(data).map((component) => {
console.log(chalk.blue('Processing', component[1], 'component.'))
const contents = XRegExp.matchRecursive(data, '<!-- @\[' + component[1] + '\][.\w-_+]* -->', '<!-- @\[/' + component[1] + '\] -->', 'g')
let body = ''
let classes = ''
contents.map((content) => {
const filteredContent = filterContent(content)
body = filteredContent.value
classes = cleanClasses(component[2])
console.log(chalk.green(component[1], 'processing complete.'))
})
// Output the content as a JSON object
return {
componentName: component[1],
classes,
body
}
})
我遇到的问题是CodeExample
标签存在两次,标签是一样的但是内容不一样,但是因为matchRecursive
好像没有回调函数,所以只是同时在该组件的所有实例上运行匹配,因此有 1 个或 10 个 CodeExample
实例并不重要,所有这些实例的内容都会返回。
有没有办法可以实际向 matchRecursive 添加某种回调?如果失败了,有没有办法让 JavaScript 了解正在查看哪个 CodeExample 实例,以便我可以直接引用数组位置?我假设 XRegexP 知道它正在查看哪个编号的 CodeExample 标记,那么有没有办法捕获它?
为了清楚起见,这里是完整的代码:https://pastebin.com/2MpdvdNA
我想要的输出是一个包含以下数据的 JSON 文件:
[
{
componentName: "hero",
classes: "",
body: "# Creating new contexts"
},
{
componentName: "CodeExample",
classes: "",
body: "## Usage example
```javascript
Import { ICON_NAME } from 'Icons'
```"
},
{
componentName: "ArticleSection",
classes: "",
body: // This section is massive and not relevant to question so skipping
},
{
componentName: "NoteBlock",
classes: ["warning"],
body: "> #### Be Careful
> Eu laboris eiusmod ut exercitation minim laboris ipsum magna consectetur est [commodo](/nope)."
},
{
componentName: "CodeExample",
classes: "",
body: "#### Code example
```javascript
class ScrollingList extends React.Component {
constructor(props) {
super(props);
this.listRef = React.createRef();
}
render() {
return (
<div ref={this.listRef}>{/* ...contents... */}</div>
);
}
}
```"
}
// Skipping the rest as not relevant to question
]
抱歉,如果我没有解释清楚,我已经看这个太久了。
最后是这样解决的:
import XRegExp from 'xregexp'
const extractComponents = data => {
const components = []
const re = '<!-- @\[(\w+)\]([.\w-_+]+)* -->'
XRegExp.forEach(data, XRegExp(re, 'g'), match => {
const name = match[1]
const classes = match[2]
const count = components.filter(item => item.name === name).length
const instance = count ? count : 0
components.push({
name,
classes,
instance
})
})
return components
}
const cleanClasses = classes => {
const filteredClasses = classes ? classes.split('.') : []
filteredClasses.shift()
return filteredClasses
}
const extractContent = (data, component) => {
const re = `<!-- @\[${component.name}\][.\w-_+]* -->`
const re2 = `<!-- @\[/${component.name}\] -->`
return XRegExp.matchRecursive(
data,
re, re2, 'g'
)[component.instance]
}
const parseComponents = data => {
return extractComponents(data).map(component => {
return {
componentName: component.name,
classes: cleanClasses(component.classes),
body: extractContent(data, component)
}
})
}
export default parseComponents