如何在正则表达式中提取两个独立的组?
How to extract two separate groups in regex?
在本文中,我试图提取以下行的所有标题和页码:
- 以 -
开头
- 后跟空格
- 然后是章节标题
- 然后是第#页,像这样:#page=9&
这是我正在使用的原始文本示例:
| "Principles of Microeconomics 2e" (null)
- "Preface" #page=9&zoom=0,0,58
| "1. About OpenStax" #page=9&zoom=0,0,150
| "2. About OpenStax resources" #page=9&zoom=0,0,248
| "3. About Principles of Microeconomics 2e" #page=9&zoom=0,0,544
| "4. Additional resources" #page=13&zoom=0,0,367
| "5. About the authors" #page=14&zoom=0,0,58
- "Chapter 1. Welcome to Economics!" #page=17&zoom=0,0,58
| "1.1. What Is Economics, and Why Is It Important?*" #page=18&zoom=0,0,338
| "1.2. Microeconomics and Macroeconomics*" #page=22&zoom=0,0,448
| "1.3. How Economists Use Theories and Models to Understand Economic Issues*" #page=23&zoom=0,0,565
我当前的正则表达式:
(?:\-\s)(["'])(?:(?=(\?)).)*?(?:page=)(?<=\=)(.*?)(?=\&)
目前使用此正则表达式匹配整行,但没有将所需元素放入单独的组中。我在进行此分隔时遇到了问题。
当前输出:
current output
期望的输出:
Match 1: "Preface" #page=9&
Group 1: Preface
Group 2: 9
Match 2: "Chapter 1. Welcome to Economics!" #page=17&
Group 1: Chapter 1. Welcome to Economics!
Group 2: 17
我试图在一组中提取标题,在另一组中提取页码。
我该怎么做?
开始于
sed -En 's/^-.*"([^"]+)".*page=([[:digit:]]+).*/\n/p' file
Preface
9
Chapter 1. Welcome to Economics!
17
sed 不使用 PCRE,因此您没有非捕获括号或环视等
更新以解决新的所需输出。
sed,没有任意变量,将很难计算匹配项。使用具有相同正则表达式的 GNU awk:
gawk '
match([=12=], /^-.*"([^"]+)".*page=([[:digit:]]+)/, m) {
printf "Match %d: %s\n", ++n, m[0]
printf "Group 1: %s\n", m[1]
printf "Group 2: %s\n\n", m[2]
}
' file
Match 1: - "Preface" #page=9
Group 1: Preface
Group 2: 9
Match 2: - "Chapter 1. Welcome to Economics!" #page=17
Group 1: Chapter 1. Welcome to Economics!
Group 2: 17
3 参数 match()
函数需要 GNU awk。
使用 GNU awk:
awk 'BEGIN{ FPAT="\".*\"|#page=[0-9]+&" }
/^- /{
print "Match", ++m ":", , ;
gsub(/"/, "", ); # remove all "
print "Group 1:", ;
gsub(/[^0-9]+/, "", ); # remove all but numbers
print "Group 2:", ;
print ""
}' file
输出:
Match 1: "Preface" #page=9&
Group 1: Preface
Group 2: 9
Match 2: "Chapter 1. Welcome to Economics!" #page=17&
Group 1: Chapter 1. Welcome to Economics!
Group 2: 17
FPAT
: A regular expression describing the contents of the fields in a record.
使用您显示的示例,请尝试执行以下 awk
程序。在 GNU awk
.
中编写和测试
awk -v RS='-[[:space:]]+"[^"]*"[[:space:]]+#page=[0-9]+' '
RT{
match(RT,/"[^"]*"/,completeValue)
printf("Match 1: - %s\nGroup 1: %s\n",RT,completeValue[0])
match(RT,/#page=[0-9]+/,pageVal)
split(pageVal[0],actualpageVal,"=")
print "Group 2: "actualpageVal[2]
}
' Input_file
解释: 简单的解释就是,将 RS(记录分隔符)设置为 -[[:space:]]+"[^"]*"[[:space:]]+#page=[0-9]+
正则表达式。然后在主程序中;匹配第 2 次 "
和创建数组 completeValue
之间的所有内容(根据所示示例,其中包含完整的值)。然后使用 awk
的 printf
函数打印 1st 2 所需的输出行(完整值和第 1 组:一个),然后再次根据要求仅从页面值中获取数字值并使用数组 actualpageVal 打印它。
在本文中,我试图提取以下行的所有标题和页码:
- 以 - 开头
- 后跟空格
- 然后是章节标题
- 然后是第#页,像这样:#page=9&
这是我正在使用的原始文本示例:
| "Principles of Microeconomics 2e" (null)
- "Preface" #page=9&zoom=0,0,58
| "1. About OpenStax" #page=9&zoom=0,0,150
| "2. About OpenStax resources" #page=9&zoom=0,0,248
| "3. About Principles of Microeconomics 2e" #page=9&zoom=0,0,544
| "4. Additional resources" #page=13&zoom=0,0,367
| "5. About the authors" #page=14&zoom=0,0,58
- "Chapter 1. Welcome to Economics!" #page=17&zoom=0,0,58
| "1.1. What Is Economics, and Why Is It Important?*" #page=18&zoom=0,0,338
| "1.2. Microeconomics and Macroeconomics*" #page=22&zoom=0,0,448
| "1.3. How Economists Use Theories and Models to Understand Economic Issues*" #page=23&zoom=0,0,565
我当前的正则表达式:
(?:\-\s)(["'])(?:(?=(\?)).)*?(?:page=)(?<=\=)(.*?)(?=\&)
目前使用此正则表达式匹配整行,但没有将所需元素放入单独的组中。我在进行此分隔时遇到了问题。
当前输出: current output
期望的输出:
Match 1: "Preface" #page=9&
Group 1: Preface
Group 2: 9
Match 2: "Chapter 1. Welcome to Economics!" #page=17&
Group 1: Chapter 1. Welcome to Economics!
Group 2: 17
我试图在一组中提取标题,在另一组中提取页码。 我该怎么做?
开始于
sed -En 's/^-.*"([^"]+)".*page=([[:digit:]]+).*/\n/p' file
Preface
9
Chapter 1. Welcome to Economics!
17
sed 不使用 PCRE,因此您没有非捕获括号或环视等
更新以解决新的所需输出。
sed,没有任意变量,将很难计算匹配项。使用具有相同正则表达式的 GNU awk:
gawk '
match([=12=], /^-.*"([^"]+)".*page=([[:digit:]]+)/, m) {
printf "Match %d: %s\n", ++n, m[0]
printf "Group 1: %s\n", m[1]
printf "Group 2: %s\n\n", m[2]
}
' file
Match 1: - "Preface" #page=9
Group 1: Preface
Group 2: 9
Match 2: - "Chapter 1. Welcome to Economics!" #page=17
Group 1: Chapter 1. Welcome to Economics!
Group 2: 17
3 参数 match()
函数需要 GNU awk。
使用 GNU awk:
awk 'BEGIN{ FPAT="\".*\"|#page=[0-9]+&" }
/^- /{
print "Match", ++m ":", , ;
gsub(/"/, "", ); # remove all "
print "Group 1:", ;
gsub(/[^0-9]+/, "", ); # remove all but numbers
print "Group 2:", ;
print ""
}' file
输出:
Match 1: "Preface" #page=9& Group 1: Preface Group 2: 9 Match 2: "Chapter 1. Welcome to Economics!" #page=17& Group 1: Chapter 1. Welcome to Economics! Group 2: 17
FPAT
: A regular expression describing the contents of the fields in a record.
使用您显示的示例,请尝试执行以下 awk
程序。在 GNU awk
.
awk -v RS='-[[:space:]]+"[^"]*"[[:space:]]+#page=[0-9]+' '
RT{
match(RT,/"[^"]*"/,completeValue)
printf("Match 1: - %s\nGroup 1: %s\n",RT,completeValue[0])
match(RT,/#page=[0-9]+/,pageVal)
split(pageVal[0],actualpageVal,"=")
print "Group 2: "actualpageVal[2]
}
' Input_file
解释: 简单的解释就是,将 RS(记录分隔符)设置为 -[[:space:]]+"[^"]*"[[:space:]]+#page=[0-9]+
正则表达式。然后在主程序中;匹配第 2 次 "
和创建数组 completeValue
之间的所有内容(根据所示示例,其中包含完整的值)。然后使用 awk
的 printf
函数打印 1st 2 所需的输出行(完整值和第 1 组:一个),然后再次根据要求仅从页面值中获取数字值并使用数组 actualpageVal 打印它。