Capturing repeating groups in GO
up vote
2
down vote
favorite
I'm trying to create a function that can parse strings which consist of an uppercase word followed by zero or more arguments which are encapsulated in double quotes.
For example, each of the following lines:
COPY "filename one" "filename two"
REMOVE "filename"
LIST "x" "y" "z"
DISCONNECT
The result should be a string (the command) followed by a string (the arguments inside the quotes). I created the following regular expression:
re1, _ := regexp.Compile(`([A-Z]+)(?: "([^"]+)")*`)
results := re1.FindAllStringSubmatch(input, -1)
However, no-matter what I try, only the last argument gets captured.
An example of my problem: https://play.golang.org/p/W1rE1X4SWf5
"arg1" is not captured in this example. What am I missing?
regex
add a comment |
up vote
2
down vote
favorite
I'm trying to create a function that can parse strings which consist of an uppercase word followed by zero or more arguments which are encapsulated in double quotes.
For example, each of the following lines:
COPY "filename one" "filename two"
REMOVE "filename"
LIST "x" "y" "z"
DISCONNECT
The result should be a string (the command) followed by a string (the arguments inside the quotes). I created the following regular expression:
re1, _ := regexp.Compile(`([A-Z]+)(?: "([^"]+)")*`)
results := re1.FindAllStringSubmatch(input, -1)
However, no-matter what I try, only the last argument gets captured.
An example of my problem: https://play.golang.org/p/W1rE1X4SWf5
"arg1" is not captured in this example. What am I missing?
regex
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 at 15:57
add a comment |
up vote
2
down vote
favorite
up vote
2
down vote
favorite
I'm trying to create a function that can parse strings which consist of an uppercase word followed by zero or more arguments which are encapsulated in double quotes.
For example, each of the following lines:
COPY "filename one" "filename two"
REMOVE "filename"
LIST "x" "y" "z"
DISCONNECT
The result should be a string (the command) followed by a string (the arguments inside the quotes). I created the following regular expression:
re1, _ := regexp.Compile(`([A-Z]+)(?: "([^"]+)")*`)
results := re1.FindAllStringSubmatch(input, -1)
However, no-matter what I try, only the last argument gets captured.
An example of my problem: https://play.golang.org/p/W1rE1X4SWf5
"arg1" is not captured in this example. What am I missing?
regex
I'm trying to create a function that can parse strings which consist of an uppercase word followed by zero or more arguments which are encapsulated in double quotes.
For example, each of the following lines:
COPY "filename one" "filename two"
REMOVE "filename"
LIST "x" "y" "z"
DISCONNECT
The result should be a string (the command) followed by a string (the arguments inside the quotes). I created the following regular expression:
re1, _ := regexp.Compile(`([A-Z]+)(?: "([^"]+)")*`)
results := re1.FindAllStringSubmatch(input, -1)
However, no-matter what I try, only the last argument gets captured.
An example of my problem: https://play.golang.org/p/W1rE1X4SWf5
"arg1" is not captured in this example. What am I missing?
regex
regex
edited Nov 22 at 16:21
mrzasa
8,054103778
8,054103778
asked Nov 22 at 15:40
Xatoo
2,2312143
2,2312143
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 at 15:57
add a comment |
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 at 15:57
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 at 15:57
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 at 15:57
add a comment |
4 Answers
4
active
oldest
votes
up vote
2
down vote
accepted
If your commands are well defined, e.i. command names are always upper-case and arguments are always after the command then a looser regex might just fit your use case:
re1, _ := regexp.Compile(`([A-Z]+)|(?: "([^"]+)")`)
results := re1.FindAllStringSubmatch(`COMMAND "arg1" "arg2" "arg3"`, -1)
fmt.Println("Command:", results[0][1])
for _, arg := range results[1:] {
fmt.Println("Arg:", arg[2])
}
Playground
Awesome, this implementation works for me!
– Xatoo
Nov 22 at 17:00
Probably,regexp.Compile(`^([A-Z]+)| "([^"]+)"`)will be more precise as it matches the command at the start of string only.
– Wiktor Stribiżew
Nov 22 at 17:25
add a comment |
up vote
1
down vote
When you try to capture repeated match, only the last one is captured.
I'd try to do it in two steps: first split commmand and arguments, then parse the arguments.
Splitting to command and arguments can be done with ([A-Z]+)((?: "[^"]+")*) (demo):
([A-Z]+)in first group, you get the command
((?: "[^"]+")*)in the second group, you'll get arguments in quotes, separated by spaces
Then you can use FindAllString with "([^"]+)" to extract arguments (demo).
add a comment |
up vote
1
down vote
I think this may solve your problem
re1, _ := regexp.Compile(`([A-Z]+)(?: *)`)
commandText:=`COPY "filename one" "filename two"`
if re1.Match(byte(commandText)){
index:=re1.FindIndex(byte(commandText))[1]
commandArgs:=commandText[index:]
commandArgsRegex,_:=regexp.Compile(`"([^"]+)"`)
fmt.Println("Command= " , commandText[0:index])
for i,arg:=range commandArgsRegex.FindAllString(commandArgs,-1){
fmt.Println("args ", i,"= " , arg)
}
}else{
fmt.Println("Failed")
}
add a comment |
up vote
0
down vote
Add an extra capture group. If you make it optional extra data will be empty but the match will work
re1, _ := regexp.Compile(`^([A-Z]+)(s"[^"]+")(s"[^"]+")?(s"[^"]+")?$`)
Add more (s"[^"]+")? expressions up to the maximum you need. I put in two as there is an expression with 3 parameters in your examples
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53434310%2fcapturing-repeating-groups-in-go%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
If your commands are well defined, e.i. command names are always upper-case and arguments are always after the command then a looser regex might just fit your use case:
re1, _ := regexp.Compile(`([A-Z]+)|(?: "([^"]+)")`)
results := re1.FindAllStringSubmatch(`COMMAND "arg1" "arg2" "arg3"`, -1)
fmt.Println("Command:", results[0][1])
for _, arg := range results[1:] {
fmt.Println("Arg:", arg[2])
}
Playground
Awesome, this implementation works for me!
– Xatoo
Nov 22 at 17:00
Probably,regexp.Compile(`^([A-Z]+)| "([^"]+)"`)will be more precise as it matches the command at the start of string only.
– Wiktor Stribiżew
Nov 22 at 17:25
add a comment |
up vote
2
down vote
accepted
If your commands are well defined, e.i. command names are always upper-case and arguments are always after the command then a looser regex might just fit your use case:
re1, _ := regexp.Compile(`([A-Z]+)|(?: "([^"]+)")`)
results := re1.FindAllStringSubmatch(`COMMAND "arg1" "arg2" "arg3"`, -1)
fmt.Println("Command:", results[0][1])
for _, arg := range results[1:] {
fmt.Println("Arg:", arg[2])
}
Playground
Awesome, this implementation works for me!
– Xatoo
Nov 22 at 17:00
Probably,regexp.Compile(`^([A-Z]+)| "([^"]+)"`)will be more precise as it matches the command at the start of string only.
– Wiktor Stribiżew
Nov 22 at 17:25
add a comment |
up vote
2
down vote
accepted
up vote
2
down vote
accepted
If your commands are well defined, e.i. command names are always upper-case and arguments are always after the command then a looser regex might just fit your use case:
re1, _ := regexp.Compile(`([A-Z]+)|(?: "([^"]+)")`)
results := re1.FindAllStringSubmatch(`COMMAND "arg1" "arg2" "arg3"`, -1)
fmt.Println("Command:", results[0][1])
for _, arg := range results[1:] {
fmt.Println("Arg:", arg[2])
}
Playground
If your commands are well defined, e.i. command names are always upper-case and arguments are always after the command then a looser regex might just fit your use case:
re1, _ := regexp.Compile(`([A-Z]+)|(?: "([^"]+)")`)
results := re1.FindAllStringSubmatch(`COMMAND "arg1" "arg2" "arg3"`, -1)
fmt.Println("Command:", results[0][1])
for _, arg := range results[1:] {
fmt.Println("Arg:", arg[2])
}
Playground
edited Nov 22 at 16:23
answered Nov 22 at 16:15
ssemilla
3,077424
3,077424
Awesome, this implementation works for me!
– Xatoo
Nov 22 at 17:00
Probably,regexp.Compile(`^([A-Z]+)| "([^"]+)"`)will be more precise as it matches the command at the start of string only.
– Wiktor Stribiżew
Nov 22 at 17:25
add a comment |
Awesome, this implementation works for me!
– Xatoo
Nov 22 at 17:00
Probably,regexp.Compile(`^([A-Z]+)| "([^"]+)"`)will be more precise as it matches the command at the start of string only.
– Wiktor Stribiżew
Nov 22 at 17:25
Awesome, this implementation works for me!
– Xatoo
Nov 22 at 17:00
Awesome, this implementation works for me!
– Xatoo
Nov 22 at 17:00
Probably,
regexp.Compile(`^([A-Z]+)| "([^"]+)"`) will be more precise as it matches the command at the start of string only.– Wiktor Stribiżew
Nov 22 at 17:25
Probably,
regexp.Compile(`^([A-Z]+)| "([^"]+)"`) will be more precise as it matches the command at the start of string only.– Wiktor Stribiżew
Nov 22 at 17:25
add a comment |
up vote
1
down vote
When you try to capture repeated match, only the last one is captured.
I'd try to do it in two steps: first split commmand and arguments, then parse the arguments.
Splitting to command and arguments can be done with ([A-Z]+)((?: "[^"]+")*) (demo):
([A-Z]+)in first group, you get the command
((?: "[^"]+")*)in the second group, you'll get arguments in quotes, separated by spaces
Then you can use FindAllString with "([^"]+)" to extract arguments (demo).
add a comment |
up vote
1
down vote
When you try to capture repeated match, only the last one is captured.
I'd try to do it in two steps: first split commmand and arguments, then parse the arguments.
Splitting to command and arguments can be done with ([A-Z]+)((?: "[^"]+")*) (demo):
([A-Z]+)in first group, you get the command
((?: "[^"]+")*)in the second group, you'll get arguments in quotes, separated by spaces
Then you can use FindAllString with "([^"]+)" to extract arguments (demo).
add a comment |
up vote
1
down vote
up vote
1
down vote
When you try to capture repeated match, only the last one is captured.
I'd try to do it in two steps: first split commmand and arguments, then parse the arguments.
Splitting to command and arguments can be done with ([A-Z]+)((?: "[^"]+")*) (demo):
([A-Z]+)in first group, you get the command
((?: "[^"]+")*)in the second group, you'll get arguments in quotes, separated by spaces
Then you can use FindAllString with "([^"]+)" to extract arguments (demo).
When you try to capture repeated match, only the last one is captured.
I'd try to do it in two steps: first split commmand and arguments, then parse the arguments.
Splitting to command and arguments can be done with ([A-Z]+)((?: "[^"]+")*) (demo):
([A-Z]+)in first group, you get the command
((?: "[^"]+")*)in the second group, you'll get arguments in quotes, separated by spaces
Then you can use FindAllString with "([^"]+)" to extract arguments (demo).
answered Nov 22 at 16:05
mrzasa
8,054103778
8,054103778
add a comment |
add a comment |
up vote
1
down vote
I think this may solve your problem
re1, _ := regexp.Compile(`([A-Z]+)(?: *)`)
commandText:=`COPY "filename one" "filename two"`
if re1.Match(byte(commandText)){
index:=re1.FindIndex(byte(commandText))[1]
commandArgs:=commandText[index:]
commandArgsRegex,_:=regexp.Compile(`"([^"]+)"`)
fmt.Println("Command= " , commandText[0:index])
for i,arg:=range commandArgsRegex.FindAllString(commandArgs,-1){
fmt.Println("args ", i,"= " , arg)
}
}else{
fmt.Println("Failed")
}
add a comment |
up vote
1
down vote
I think this may solve your problem
re1, _ := regexp.Compile(`([A-Z]+)(?: *)`)
commandText:=`COPY "filename one" "filename two"`
if re1.Match(byte(commandText)){
index:=re1.FindIndex(byte(commandText))[1]
commandArgs:=commandText[index:]
commandArgsRegex,_:=regexp.Compile(`"([^"]+)"`)
fmt.Println("Command= " , commandText[0:index])
for i,arg:=range commandArgsRegex.FindAllString(commandArgs,-1){
fmt.Println("args ", i,"= " , arg)
}
}else{
fmt.Println("Failed")
}
add a comment |
up vote
1
down vote
up vote
1
down vote
I think this may solve your problem
re1, _ := regexp.Compile(`([A-Z]+)(?: *)`)
commandText:=`COPY "filename one" "filename two"`
if re1.Match(byte(commandText)){
index:=re1.FindIndex(byte(commandText))[1]
commandArgs:=commandText[index:]
commandArgsRegex,_:=regexp.Compile(`"([^"]+)"`)
fmt.Println("Command= " , commandText[0:index])
for i,arg:=range commandArgsRegex.FindAllString(commandArgs,-1){
fmt.Println("args ", i,"= " , arg)
}
}else{
fmt.Println("Failed")
}
I think this may solve your problem
re1, _ := regexp.Compile(`([A-Z]+)(?: *)`)
commandText:=`COPY "filename one" "filename two"`
if re1.Match(byte(commandText)){
index:=re1.FindIndex(byte(commandText))[1]
commandArgs:=commandText[index:]
commandArgsRegex,_:=regexp.Compile(`"([^"]+)"`)
fmt.Println("Command= " , commandText[0:index])
for i,arg:=range commandArgsRegex.FindAllString(commandArgs,-1){
fmt.Println("args ", i,"= " , arg)
}
}else{
fmt.Println("Failed")
}
answered Nov 22 at 16:10
Ehsan.Saradar
45337
45337
add a comment |
add a comment |
up vote
0
down vote
Add an extra capture group. If you make it optional extra data will be empty but the match will work
re1, _ := regexp.Compile(`^([A-Z]+)(s"[^"]+")(s"[^"]+")?(s"[^"]+")?$`)
Add more (s"[^"]+")? expressions up to the maximum you need. I put in two as there is an expression with 3 parameters in your examples
add a comment |
up vote
0
down vote
Add an extra capture group. If you make it optional extra data will be empty but the match will work
re1, _ := regexp.Compile(`^([A-Z]+)(s"[^"]+")(s"[^"]+")?(s"[^"]+")?$`)
Add more (s"[^"]+")? expressions up to the maximum you need. I put in two as there is an expression with 3 parameters in your examples
add a comment |
up vote
0
down vote
up vote
0
down vote
Add an extra capture group. If you make it optional extra data will be empty but the match will work
re1, _ := regexp.Compile(`^([A-Z]+)(s"[^"]+")(s"[^"]+")?(s"[^"]+")?$`)
Add more (s"[^"]+")? expressions up to the maximum you need. I put in two as there is an expression with 3 parameters in your examples
Add an extra capture group. If you make it optional extra data will be empty but the match will work
re1, _ := regexp.Compile(`^([A-Z]+)(s"[^"]+")(s"[^"]+")?(s"[^"]+")?$`)
Add more (s"[^"]+")? expressions up to the maximum you need. I put in two as there is an expression with 3 parameters in your examples
answered Nov 22 at 16:25
Vorsprung
22.1k31941
22.1k31941
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53434310%2fcapturing-repeating-groups-in-go%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 at 15:57