Capturing repeating groups in GO
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 go
add a comment |
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 go
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 '18 at 15:57
add a comment |
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 go
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 go
regex go
edited Nov 22 '18 at 16:21
mrzasa
10.6k104078
10.6k104078
asked Nov 22 '18 at 15:40
XatooXatoo
2,2962144
2,2962144
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 '18 at 15:57
add a comment |
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 '18 at 15:57
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 '18 at 15:57
Could a command (without considering args) contain white space?
– Ehsan.Saradar
Nov 22 '18 at 15:57
add a comment |
4 Answers
4
active
oldest
votes
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 '18 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 '18 at 17:25
add a comment |
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 |
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 |
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
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 '18 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 '18 at 17:25
add a comment |
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 '18 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 '18 at 17:25
add a comment |
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 '18 at 16:23
answered Nov 22 '18 at 16:15
ssemillassemilla
3,097524
3,097524
Awesome, this implementation works for me!
– Xatoo
Nov 22 '18 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 '18 at 17:25
add a comment |
Awesome, this implementation works for me!
– Xatoo
Nov 22 '18 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 '18 at 17:25
Awesome, this implementation works for me!
– Xatoo
Nov 22 '18 at 17:00
Awesome, this implementation works for me!
– Xatoo
Nov 22 '18 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 '18 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 '18 at 17:25
add a comment |
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 |
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 |
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 '18 at 16:05
mrzasamrzasa
10.6k104078
10.6k104078
add a comment |
add a comment |
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 |
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 |
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 '18 at 16:10
Ehsan.SaradarEhsan.Saradar
46337
46337
add a comment |
add a comment |
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 |
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 |
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 '18 at 16:25
VorsprungVorsprung
23.2k32144
23.2k32144
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.
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 '18 at 15:57