动态清理字符串
Cleaning Strings dynamically
我在学习 puppeteer
时将网页作为一个有趣的小项目进行抓取,在那段时间里,我 运行 在清理字符串以获取 有用的数据。我想出了一些从他们那里提取我想要的数据的简单方法,但我 运行 陷入边缘情况,我不知道最好的处理方式。
取这个字符串
Round 1 - Foo Bar (SchoolName) over John (JC) Cena (Fake School Name) (Fall 1:19)
我要获取的数据
- 获奖者姓名 = Foo Bar
- 获胜者的学校 =(学校名称)
- 失败者的名字=约翰·塞纳
- 失败者学校 = 假学校名称
Round 1
和 -
对我没用,它们在整个应用程序中遵循相同的结构。因此,使用仅选择这些项目所在位置的索引的方法应该非常简单。
这个字符串中最重要的索引是over
所在的位置。一旦找到它,我就可以搜索它周围的索引,找到我需要的其余信息在哪里。
let findOver = arr.indexOf('over')
let winnerName = arr[over - 3].concat(' ', arr[over - 2])
let winnerSchool = summaryBreakUp[over - 1]
这对上面的字符串有效,至少对左侧有效。它获取获胜者的名字和姓氏并将它们连接起来。
我的问题是当字符串看起来不像左侧时,我如何 考虑上面的边缘情况。
我可以搜索所有 ( && )
并捕获其中的所有数据以获得 School Names
但随后我需要筛选一种方法来确定哪一个是学校和哪个是昵称
如有任何指示,我们将不胜感激。我还会 post 一些更多的例子,以防其他人想尝试一下。
这是对未指定对手的胜利。
Michael Macontish (Fairview) over Unknown (For.)
没有给出回合
John Heflin (Arlington) over Random Kid (Mistview) (Fall 1:59)
没有 下降 给予
Round 2 - Logan Paul George (High School) over Dontae Inverse (Jackson County) (Dec 3-0)
使用正则表达式和捕获组来获取您感兴趣的位,您可能需要做一些小的整理工作。
您可以使用许多模式(我相信这不是最好的,但它是一个开始):
([\w\s\(\)]+)\s\(([\s\w\.]+)\)\sover\s([\w\s\(\)]+)\s\(([\s\w\.]+)\)
这与名字相匹配
- 任何字母数字、下划线、空格或括号
- 出现一次或多次
后跟左括号,后跟学校为
- 任何空格、字母数字、下划线或句点
- 出现一次或多次
后跟一个右括号,然后是空格,然后是单词“over”,再次是空格,然后重复名称和学校模式。其他一切都被忽略。
用法:当您在 javascript 中使用正则表达式时,捕获组最终作为结果数组中的元素。整个匹配是第一个元素,每个附加元素按顺序表示捕获组。此表达式中有 4 个捕获组,因此您最终会得到代表 name1、school1、name2 和 school2 的元素 1-5。
const re = /([\w\s\(\)]+)\s\(([\s\w\.]+)\)\sover\s([\w\s\(\)]+)\s\(([\s\w\.]+)\)/
const input = [
'Round 1 - Foo Bar (SchoolName) over John (JC) Cena (Fake School Name) (Fall 1:19)',
'Michael Macontish (Fairview) over Unknown (For.)',
'John Heflin (Arlington) over Random Kid (Mistview) (Fall 1:59)',
'Round 2 - Logan Paul George (High School) over Dontae Inverse (Jackson County) (Dec 3-0)'
]
input.forEach( i => {
console.log(i.match(re))
})
作为替代模式,您可以使用非贪婪点扩大匹配范围 .*?
以匹配任何字符或否定字符 class [^
以排除允许的内容待匹配。
开始模式,可选择匹配开头的部分 -
。
要匹配末尾括号之间的正确部分,您可以断言括号之间的部分没有 - 或 : 数字之间使用负先行。
(?:.*?\s+-\s+)?([^()]+)\s+\(([^()]+)\)\s+over\s+(.*)\s+\((?![^()]*\d[-:]\d[^()]*\))([^()]*)\)
模式匹配:
(?:.*?\s+-\s+)?
可选择匹配以 <code> - </code>
结尾的部分
([^()]+)
捕获 组 1 以匹配除 (
和 )
之外的任何字符
\s+
匹配 1+ 个空白字符
\(([^()]+)\)
匹配 (
然后捕获 组 2 中除 (
和 )
之外的任何字符并匹配 )
- \s+over\s+
Match
over` 在 1 个或多个空白字符之间
(.*)
捕获 组 3 中的任何字符
\s+
匹配 1+ 个空白字符
\(
匹配 (
(?![^()]*\d[-:]\d[^()]*\))
否定前瞻,断言括号之间没有 :
或 -
之间的数字
([^()]*)
如果断言为真,则捕获 group 4 中除 (
和 )
之外的任何字符
\)
匹配 )
看到一个regex demo
const regex = /(?:.*?\s+-\s+)?([^()]+)\s+\(([^()]+)\)\s+over\s+(.*)\s+\((?![^()]*\d[-:]\d[^()]*\))([^()\n]*)\)/;
[
"Round 1 - Foo Bar (SchoolName) over John (JC) Cena (Fake School Name) (Fall 1:19)",
"Michael Macontish (Fairview) over Unknown (For.)",
"John Heflin (Arlington) over Random Kid (Mistview) (Fall 1:59)",
"Round 2 - Logan Paul George (High School) over Dontae Inverse (Jackson County) (Dec 3-0)"
].forEach(s => console.log(s.match(regex)));
我在学习 puppeteer
时将网页作为一个有趣的小项目进行抓取,在那段时间里,我 运行 在清理字符串以获取 有用的数据。我想出了一些从他们那里提取我想要的数据的简单方法,但我 运行 陷入边缘情况,我不知道最好的处理方式。
取这个字符串
Round 1 - Foo Bar (SchoolName) over John (JC) Cena (Fake School Name) (Fall 1:19)
我要获取的数据
- 获奖者姓名 = Foo Bar
- 获胜者的学校 =(学校名称)
- 失败者的名字=约翰·塞纳
- 失败者学校 = 假学校名称
Round 1
和 -
对我没用,它们在整个应用程序中遵循相同的结构。因此,使用仅选择这些项目所在位置的索引的方法应该非常简单。
这个字符串中最重要的索引是over
所在的位置。一旦找到它,我就可以搜索它周围的索引,找到我需要的其余信息在哪里。
let findOver = arr.indexOf('over')
let winnerName = arr[over - 3].concat(' ', arr[over - 2])
let winnerSchool = summaryBreakUp[over - 1]
这对上面的字符串有效,至少对左侧有效。它获取获胜者的名字和姓氏并将它们连接起来。
我的问题是当字符串看起来不像左侧时,我如何 考虑上面的边缘情况。
我可以搜索所有 ( && )
并捕获其中的所有数据以获得 School Names
但随后我需要筛选一种方法来确定哪一个是学校和哪个是昵称
如有任何指示,我们将不胜感激。我还会 post 一些更多的例子,以防其他人想尝试一下。
这是对未指定对手的胜利。
Michael Macontish (Fairview) over Unknown (For.)
没有给出回合
John Heflin (Arlington) over Random Kid (Mistview) (Fall 1:59)
没有 下降 给予
Round 2 - Logan Paul George (High School) over Dontae Inverse (Jackson County) (Dec 3-0)
使用正则表达式和捕获组来获取您感兴趣的位,您可能需要做一些小的整理工作。
您可以使用许多模式(我相信这不是最好的,但它是一个开始):
([\w\s\(\)]+)\s\(([\s\w\.]+)\)\sover\s([\w\s\(\)]+)\s\(([\s\w\.]+)\)
这与名字相匹配
- 任何字母数字、下划线、空格或括号
- 出现一次或多次
后跟左括号,后跟学校为
- 任何空格、字母数字、下划线或句点
- 出现一次或多次
后跟一个右括号,然后是空格,然后是单词“over”,再次是空格,然后重复名称和学校模式。其他一切都被忽略。
用法:当您在 javascript 中使用正则表达式时,捕获组最终作为结果数组中的元素。整个匹配是第一个元素,每个附加元素按顺序表示捕获组。此表达式中有 4 个捕获组,因此您最终会得到代表 name1、school1、name2 和 school2 的元素 1-5。
const re = /([\w\s\(\)]+)\s\(([\s\w\.]+)\)\sover\s([\w\s\(\)]+)\s\(([\s\w\.]+)\)/
const input = [
'Round 1 - Foo Bar (SchoolName) over John (JC) Cena (Fake School Name) (Fall 1:19)',
'Michael Macontish (Fairview) over Unknown (For.)',
'John Heflin (Arlington) over Random Kid (Mistview) (Fall 1:59)',
'Round 2 - Logan Paul George (High School) over Dontae Inverse (Jackson County) (Dec 3-0)'
]
input.forEach( i => {
console.log(i.match(re))
})
作为替代模式,您可以使用非贪婪点扩大匹配范围 .*?
以匹配任何字符或否定字符 class [^
以排除允许的内容待匹配。
开始模式,可选择匹配开头的部分 -
。
要匹配末尾括号之间的正确部分,您可以断言括号之间的部分没有 - 或 : 数字之间使用负先行。
(?:.*?\s+-\s+)?([^()]+)\s+\(([^()]+)\)\s+over\s+(.*)\s+\((?![^()]*\d[-:]\d[^()]*\))([^()]*)\)
模式匹配:
(?:.*?\s+-\s+)?
可选择匹配以<code> - </code>
结尾的部分
([^()]+)
捕获 组 1 以匹配除(
和)
之外的任何字符
\s+
匹配 1+ 个空白字符\(([^()]+)\)
匹配(
然后捕获 组 2 中除(
和)
之外的任何字符并匹配)
- \s+over\s+
Match
over` 在 1 个或多个空白字符之间 (.*)
捕获 组 3 中的任何字符
\s+
匹配 1+ 个空白字符\(
匹配(
(?![^()]*\d[-:]\d[^()]*\))
否定前瞻,断言括号之间没有:
或-
之间的数字([^()]*)
如果断言为真,则捕获 group 4 中除 \)
匹配)
(
和 )
之外的任何字符
看到一个regex demo
const regex = /(?:.*?\s+-\s+)?([^()]+)\s+\(([^()]+)\)\s+over\s+(.*)\s+\((?![^()]*\d[-:]\d[^()]*\))([^()\n]*)\)/;
[
"Round 1 - Foo Bar (SchoolName) over John (JC) Cena (Fake School Name) (Fall 1:19)",
"Michael Macontish (Fairview) over Unknown (For.)",
"John Heflin (Arlington) over Random Kid (Mistview) (Fall 1:59)",
"Round 2 - Logan Paul George (High School) over Dontae Inverse (Jackson County) (Dec 3-0)"
].forEach(s => console.log(s.match(regex)));