Regex to match string not inside parentheses
I been struggling to find a Regex that help me match 3 different strings only if they aren't inside parentheses, but so far I have only managed to match it if it's right next to the parentheses, and in this specific situation it doesn't suit me.
To clarify I need to match the Strings "HAVING", "ORDER BY" and "GROUP BY" that aren't contained in any parentheses, no matter if the parentheses contains more than just the string.
In that case:
Select *
from some_table
group by something;
Should match, but:
Select *
from(
Select *
from some_other_table
group by something_else
)
or
Select this, and_this
from(
Select *
from some_other_table
having some_condition
)
shouldn't.
I'm not an expert in Javascript Regex, so any help you could give me would be greatly appreciated.
javascript regex string
migrated from superuser.com Jan 6 at 15:13
This question came from our site for computer enthusiasts and power users.
add a comment |
I been struggling to find a Regex that help me match 3 different strings only if they aren't inside parentheses, but so far I have only managed to match it if it's right next to the parentheses, and in this specific situation it doesn't suit me.
To clarify I need to match the Strings "HAVING", "ORDER BY" and "GROUP BY" that aren't contained in any parentheses, no matter if the parentheses contains more than just the string.
In that case:
Select *
from some_table
group by something;
Should match, but:
Select *
from(
Select *
from some_other_table
group by something_else
)
or
Select this, and_this
from(
Select *
from some_other_table
having some_condition
)
shouldn't.
I'm not an expert in Javascript Regex, so any help you could give me would be greatly appreciated.
javascript regex string
migrated from superuser.com Jan 6 at 15:13
This question came from our site for computer enthusiasts and power users.
Can your code also contain strings or comments (and parentheses within those)? Such as:select * from stuff where x = '('
orselect 42 -- just a comment (
.
– melpomene
Jan 6 at 15:18
You need to add more information about what the string can or can't be to have a proper answer
– Dimitri Kopriwa
Jan 6 at 15:24
add a comment |
I been struggling to find a Regex that help me match 3 different strings only if they aren't inside parentheses, but so far I have only managed to match it if it's right next to the parentheses, and in this specific situation it doesn't suit me.
To clarify I need to match the Strings "HAVING", "ORDER BY" and "GROUP BY" that aren't contained in any parentheses, no matter if the parentheses contains more than just the string.
In that case:
Select *
from some_table
group by something;
Should match, but:
Select *
from(
Select *
from some_other_table
group by something_else
)
or
Select this, and_this
from(
Select *
from some_other_table
having some_condition
)
shouldn't.
I'm not an expert in Javascript Regex, so any help you could give me would be greatly appreciated.
javascript regex string
I been struggling to find a Regex that help me match 3 different strings only if they aren't inside parentheses, but so far I have only managed to match it if it's right next to the parentheses, and in this specific situation it doesn't suit me.
To clarify I need to match the Strings "HAVING", "ORDER BY" and "GROUP BY" that aren't contained in any parentheses, no matter if the parentheses contains more than just the string.
In that case:
Select *
from some_table
group by something;
Should match, but:
Select *
from(
Select *
from some_other_table
group by something_else
)
or
Select this, and_this
from(
Select *
from some_other_table
having some_condition
)
shouldn't.
I'm not an expert in Javascript Regex, so any help you could give me would be greatly appreciated.
javascript regex string
javascript regex string
edited Jan 6 at 16:00
melpomene
60.6k54793
60.6k54793
asked Jan 4 at 0:51
Steven GuerreroSteven Guerrero
528
528
migrated from superuser.com Jan 6 at 15:13
This question came from our site for computer enthusiasts and power users.
migrated from superuser.com Jan 6 at 15:13
This question came from our site for computer enthusiasts and power users.
Can your code also contain strings or comments (and parentheses within those)? Such as:select * from stuff where x = '('
orselect 42 -- just a comment (
.
– melpomene
Jan 6 at 15:18
You need to add more information about what the string can or can't be to have a proper answer
– Dimitri Kopriwa
Jan 6 at 15:24
add a comment |
Can your code also contain strings or comments (and parentheses within those)? Such as:select * from stuff where x = '('
orselect 42 -- just a comment (
.
– melpomene
Jan 6 at 15:18
You need to add more information about what the string can or can't be to have a proper answer
– Dimitri Kopriwa
Jan 6 at 15:24
Can your code also contain strings or comments (and parentheses within those)? Such as:
select * from stuff where x = '('
or select 42 -- just a comment (
.– melpomene
Jan 6 at 15:18
Can your code also contain strings or comments (and parentheses within those)? Such as:
select * from stuff where x = '('
or select 42 -- just a comment (
.– melpomene
Jan 6 at 15:18
You need to add more information about what the string can or can't be to have a proper answer
– Dimitri Kopriwa
Jan 6 at 15:24
You need to add more information about what the string can or can't be to have a proper answer
– Dimitri Kopriwa
Jan 6 at 15:24
add a comment |
1 Answer
1
active
oldest
votes
I assume you want to check whether a given SQL query contains HAVING
, ORDER BY
or GROUP BY
at the top level (not within a subquery).
This is complicated by the fact that both parens and words can be contained inside of string literals ('...'
), quoted identifiers ("..."
), and comments (-- ...
).
In the following code I assume that that's all that can "go wrong" (i.e. there are no other quoting constructs) and that no quoted characters are special (in particular, isn't treated any differently).
Idea:
- Remove all quoted constructs like string literals and comments.
- Remove all parenthesized groups.
- Check the remaining string for your keywords.
And by "remove" I mean "replace by a space" because otherwise there is the possibility of new tokens being created where there were none before (e.g. hav(...)IN"asdf"g
would turn into havINg
if parenthesized/quoted parts were just replaced by nothing).
Implementation:
function contains_groupy_bits(sql) {
sql = sql.replace(/'[^']*'|"[^"]*"|--[^n]*/g, ' ');
let tmp;
while ((tmp = sql.replace(/([^()]*)/g, ' ')) !== sql) {
sql = tmp;
}
return /b(?:having|orders+by|groups+by)b/i.test(sql);
}
const examples = [
`Select *
from some_table
group by something;`,
`Select *
from(
Select *
from some_other_table
group by something_else
)`,
`Select this, and_this
from(
Select *
from some_other_table
having some_condition
)`,
`select name, count(*) from things
where mark = '('
group by name -- )`,
];
for (const ex of examples) {
console.log("'" + ex + "': " + contains_groupy_bits(ex));
}
Quite close, but still matches the strings inside parentheses.
– Steven Guerrero
Jan 6 at 18:21
@StevenGuerrero No, it doesn't. Did you try it?
– melpomene
Jan 6 at 19:38
@melpomeme You're right it does XD I was quite in a rush, I didn't used the function but only copied the regex :v However, just tried it works, Thank you
– Steven Guerrero
Jan 8 at 1:37
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%2f54062882%2fregex-to-match-string-not-inside-parentheses%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I assume you want to check whether a given SQL query contains HAVING
, ORDER BY
or GROUP BY
at the top level (not within a subquery).
This is complicated by the fact that both parens and words can be contained inside of string literals ('...'
), quoted identifiers ("..."
), and comments (-- ...
).
In the following code I assume that that's all that can "go wrong" (i.e. there are no other quoting constructs) and that no quoted characters are special (in particular, isn't treated any differently).
Idea:
- Remove all quoted constructs like string literals and comments.
- Remove all parenthesized groups.
- Check the remaining string for your keywords.
And by "remove" I mean "replace by a space" because otherwise there is the possibility of new tokens being created where there were none before (e.g. hav(...)IN"asdf"g
would turn into havINg
if parenthesized/quoted parts were just replaced by nothing).
Implementation:
function contains_groupy_bits(sql) {
sql = sql.replace(/'[^']*'|"[^"]*"|--[^n]*/g, ' ');
let tmp;
while ((tmp = sql.replace(/([^()]*)/g, ' ')) !== sql) {
sql = tmp;
}
return /b(?:having|orders+by|groups+by)b/i.test(sql);
}
const examples = [
`Select *
from some_table
group by something;`,
`Select *
from(
Select *
from some_other_table
group by something_else
)`,
`Select this, and_this
from(
Select *
from some_other_table
having some_condition
)`,
`select name, count(*) from things
where mark = '('
group by name -- )`,
];
for (const ex of examples) {
console.log("'" + ex + "': " + contains_groupy_bits(ex));
}
Quite close, but still matches the strings inside parentheses.
– Steven Guerrero
Jan 6 at 18:21
@StevenGuerrero No, it doesn't. Did you try it?
– melpomene
Jan 6 at 19:38
@melpomeme You're right it does XD I was quite in a rush, I didn't used the function but only copied the regex :v However, just tried it works, Thank you
– Steven Guerrero
Jan 8 at 1:37
add a comment |
I assume you want to check whether a given SQL query contains HAVING
, ORDER BY
or GROUP BY
at the top level (not within a subquery).
This is complicated by the fact that both parens and words can be contained inside of string literals ('...'
), quoted identifiers ("..."
), and comments (-- ...
).
In the following code I assume that that's all that can "go wrong" (i.e. there are no other quoting constructs) and that no quoted characters are special (in particular, isn't treated any differently).
Idea:
- Remove all quoted constructs like string literals and comments.
- Remove all parenthesized groups.
- Check the remaining string for your keywords.
And by "remove" I mean "replace by a space" because otherwise there is the possibility of new tokens being created where there were none before (e.g. hav(...)IN"asdf"g
would turn into havINg
if parenthesized/quoted parts were just replaced by nothing).
Implementation:
function contains_groupy_bits(sql) {
sql = sql.replace(/'[^']*'|"[^"]*"|--[^n]*/g, ' ');
let tmp;
while ((tmp = sql.replace(/([^()]*)/g, ' ')) !== sql) {
sql = tmp;
}
return /b(?:having|orders+by|groups+by)b/i.test(sql);
}
const examples = [
`Select *
from some_table
group by something;`,
`Select *
from(
Select *
from some_other_table
group by something_else
)`,
`Select this, and_this
from(
Select *
from some_other_table
having some_condition
)`,
`select name, count(*) from things
where mark = '('
group by name -- )`,
];
for (const ex of examples) {
console.log("'" + ex + "': " + contains_groupy_bits(ex));
}
Quite close, but still matches the strings inside parentheses.
– Steven Guerrero
Jan 6 at 18:21
@StevenGuerrero No, it doesn't. Did you try it?
– melpomene
Jan 6 at 19:38
@melpomeme You're right it does XD I was quite in a rush, I didn't used the function but only copied the regex :v However, just tried it works, Thank you
– Steven Guerrero
Jan 8 at 1:37
add a comment |
I assume you want to check whether a given SQL query contains HAVING
, ORDER BY
or GROUP BY
at the top level (not within a subquery).
This is complicated by the fact that both parens and words can be contained inside of string literals ('...'
), quoted identifiers ("..."
), and comments (-- ...
).
In the following code I assume that that's all that can "go wrong" (i.e. there are no other quoting constructs) and that no quoted characters are special (in particular, isn't treated any differently).
Idea:
- Remove all quoted constructs like string literals and comments.
- Remove all parenthesized groups.
- Check the remaining string for your keywords.
And by "remove" I mean "replace by a space" because otherwise there is the possibility of new tokens being created where there were none before (e.g. hav(...)IN"asdf"g
would turn into havINg
if parenthesized/quoted parts were just replaced by nothing).
Implementation:
function contains_groupy_bits(sql) {
sql = sql.replace(/'[^']*'|"[^"]*"|--[^n]*/g, ' ');
let tmp;
while ((tmp = sql.replace(/([^()]*)/g, ' ')) !== sql) {
sql = tmp;
}
return /b(?:having|orders+by|groups+by)b/i.test(sql);
}
const examples = [
`Select *
from some_table
group by something;`,
`Select *
from(
Select *
from some_other_table
group by something_else
)`,
`Select this, and_this
from(
Select *
from some_other_table
having some_condition
)`,
`select name, count(*) from things
where mark = '('
group by name -- )`,
];
for (const ex of examples) {
console.log("'" + ex + "': " + contains_groupy_bits(ex));
}
I assume you want to check whether a given SQL query contains HAVING
, ORDER BY
or GROUP BY
at the top level (not within a subquery).
This is complicated by the fact that both parens and words can be contained inside of string literals ('...'
), quoted identifiers ("..."
), and comments (-- ...
).
In the following code I assume that that's all that can "go wrong" (i.e. there are no other quoting constructs) and that no quoted characters are special (in particular, isn't treated any differently).
Idea:
- Remove all quoted constructs like string literals and comments.
- Remove all parenthesized groups.
- Check the remaining string for your keywords.
And by "remove" I mean "replace by a space" because otherwise there is the possibility of new tokens being created where there were none before (e.g. hav(...)IN"asdf"g
would turn into havINg
if parenthesized/quoted parts were just replaced by nothing).
Implementation:
function contains_groupy_bits(sql) {
sql = sql.replace(/'[^']*'|"[^"]*"|--[^n]*/g, ' ');
let tmp;
while ((tmp = sql.replace(/([^()]*)/g, ' ')) !== sql) {
sql = tmp;
}
return /b(?:having|orders+by|groups+by)b/i.test(sql);
}
const examples = [
`Select *
from some_table
group by something;`,
`Select *
from(
Select *
from some_other_table
group by something_else
)`,
`Select this, and_this
from(
Select *
from some_other_table
having some_condition
)`,
`select name, count(*) from things
where mark = '('
group by name -- )`,
];
for (const ex of examples) {
console.log("'" + ex + "': " + contains_groupy_bits(ex));
}
function contains_groupy_bits(sql) {
sql = sql.replace(/'[^']*'|"[^"]*"|--[^n]*/g, ' ');
let tmp;
while ((tmp = sql.replace(/([^()]*)/g, ' ')) !== sql) {
sql = tmp;
}
return /b(?:having|orders+by|groups+by)b/i.test(sql);
}
const examples = [
`Select *
from some_table
group by something;`,
`Select *
from(
Select *
from some_other_table
group by something_else
)`,
`Select this, and_this
from(
Select *
from some_other_table
having some_condition
)`,
`select name, count(*) from things
where mark = '('
group by name -- )`,
];
for (const ex of examples) {
console.log("'" + ex + "': " + contains_groupy_bits(ex));
}
function contains_groupy_bits(sql) {
sql = sql.replace(/'[^']*'|"[^"]*"|--[^n]*/g, ' ');
let tmp;
while ((tmp = sql.replace(/([^()]*)/g, ' ')) !== sql) {
sql = tmp;
}
return /b(?:having|orders+by|groups+by)b/i.test(sql);
}
const examples = [
`Select *
from some_table
group by something;`,
`Select *
from(
Select *
from some_other_table
group by something_else
)`,
`Select this, and_this
from(
Select *
from some_other_table
having some_condition
)`,
`select name, count(*) from things
where mark = '('
group by name -- )`,
];
for (const ex of examples) {
console.log("'" + ex + "': " + contains_groupy_bits(ex));
}
edited Jan 6 at 16:03
answered Jan 6 at 15:57
melpomenemelpomene
60.6k54793
60.6k54793
Quite close, but still matches the strings inside parentheses.
– Steven Guerrero
Jan 6 at 18:21
@StevenGuerrero No, it doesn't. Did you try it?
– melpomene
Jan 6 at 19:38
@melpomeme You're right it does XD I was quite in a rush, I didn't used the function but only copied the regex :v However, just tried it works, Thank you
– Steven Guerrero
Jan 8 at 1:37
add a comment |
Quite close, but still matches the strings inside parentheses.
– Steven Guerrero
Jan 6 at 18:21
@StevenGuerrero No, it doesn't. Did you try it?
– melpomene
Jan 6 at 19:38
@melpomeme You're right it does XD I was quite in a rush, I didn't used the function but only copied the regex :v However, just tried it works, Thank you
– Steven Guerrero
Jan 8 at 1:37
Quite close, but still matches the strings inside parentheses.
– Steven Guerrero
Jan 6 at 18:21
Quite close, but still matches the strings inside parentheses.
– Steven Guerrero
Jan 6 at 18:21
@StevenGuerrero No, it doesn't. Did you try it?
– melpomene
Jan 6 at 19:38
@StevenGuerrero No, it doesn't. Did you try it?
– melpomene
Jan 6 at 19:38
@melpomeme You're right it does XD I was quite in a rush, I didn't used the function but only copied the regex :v However, just tried it works, Thank you
– Steven Guerrero
Jan 8 at 1:37
@melpomeme You're right it does XD I was quite in a rush, I didn't used the function but only copied the regex :v However, just tried it works, Thank you
– Steven Guerrero
Jan 8 at 1:37
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%2f54062882%2fregex-to-match-string-not-inside-parentheses%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
Can your code also contain strings or comments (and parentheses within those)? Such as:
select * from stuff where x = '('
orselect 42 -- just a comment (
.– melpomene
Jan 6 at 15:18
You need to add more information about what the string can or can't be to have a proper answer
– Dimitri Kopriwa
Jan 6 at 15:24