|
Given the name of an SQL table, I am looking to add quotes as necessary (with an loose definition of "necessary"). With SQL Server, the parts of the name should be wrapped in brackets ([ and ] ), MySQL uses backticks (` ). So, for example:
database.schema.table
database.schema.[table]
database.[schema].table
[database].[schema].table
should all be transformed to:
[database].[schema].[table]
What I have working; is capturing Wrapped and Unwrapped sections separately, wrapping the Unwrapped sections, and joining the sections back together. But it occurred to me that if I could Match only the Unwrapped sections, I could use Replace.
However, I have so far been unsuccessful in my attempts (otherwise I wouldn't be posting). Does anyone out there have an idea of how to do this? I'm thinking it may involve Balancing Groups, but I've never used them before so I'm finding them confusing.
This is not urgent.
Edit: I must have been over-thinking it . What I have now is (?<=^|\.)[^\[\]\.]+(?=$|\.)
modified 24-Jan-12 11:00am.
|
|
|
|
|
Are you looking for this?
string sql = @"database.schema.table
database.schema.[table]
database.[schema].table
[database].[schema].table
should all be transformed to:
[database].[schema].[table]
";
string pattern = @"(?:\[?(\w+)\]?)?\.\[?(\w+)\]?";
Func<Match, string> replace = m =>
(m.Groups[1].Success ? "[" + m.Groups[1].Value + "]" : "") + ".[" + m.Groups[2].Value + "]";
Console.WriteLine("{0}", Regex.Replace(sql, pattern, m=>replace(m)));
|
|
|
|
|
Does that work for names that contain SPACEs? my database.my schema.my table
And Excel worksheet names that include a dollar sign ($) at the end?
(I realize those were not listed in the original spec.)
|
|
|
|
|
You will run into problems here.
The problem arises with spaces in the name, since the following pattern:
...([\w\s]+)...
matches
delete my database
as well as
delete database
In this case I guess you don't get away without a parser (use the Regex for tokenizing, use the parser to detect all commands and translate the arguments where needed).
Any names without spaces get easily translated, though, e.g.:
string pattern = @"(?:\[?([\w\$]+)\]?)?\.\[?([\w\$]+)\]?";
And if you have optional spaces around "[" and ".", the following a bit more complicted regex will do:
...
string open = @"(?:\[\s*?)?";
string close = @"(?:\s*?\])?";
string ident = @"([\w\$]+)";
string prefix = @"(?:" + open + ident + close + @"\s*?)?";
string suffix = @"(?:" + open + ident + close + @")";
string pattern = prefix + @"\.\s*?" + suffix;
...
|
|
|
|
|
Andreas Gieriet wrote: matches
delete my database as well
as
delete database
I expect the string to contain only the database, schema, and table names.
|
|
|
|
|
The Regex sees a line like
aaa bbb ccc . ddd . eee fff
What part of aaa bbb ccc is the database name? Only ccc or bbb ccc , etc.? You see the problem?
The same for eee fff .
Non-escaped/non-wrapped spaces in names is guess work to make them wrapped into [...] .
I.e. to get from aaa bbb ccc .... to aaa [bbb ccc] .... is rather difficult, unless you know what aaa means or you say from outside that bbb ccc is a single name.
Quite a challenge.
Cheers
Andi
|
|
|
|
|
That should result in
[aaa bbb ccc ].[ ddd ].[ eee fff]
|
|
|
|
|
The line
aaa bbb ccc.ddd eee ...
could be
ALTER TABLE dbo.tVersion ADD ...
which in your approach would result in
[ALTER TABLE dbo].[tVersion ADD] ...
Forget about spaces or get as input the individual names (db name, table name, etc.) or make a parser that detects all language constructs and their db, table, etc. positions...
I still think it's not worth the effort with names that contain spaces - too fragile.
Cheers
Andi
|
|
|
|
|
No, the string contains only the database, schema, and table name separated by periods as per the original post.
|
|
|
|
|
I was confused since I understood (say: assumed...) that you have an SQL script that you want to patch... Never assume anything
In that case your initial regex is probably the simplest solution.
Cheers
Andi
|
|
|
|
|
Wait till Smitha tackles that post!
|
|
|
|
|
Hi Luc,
Aaaah! You read my whine...
I was quite upset - but I cooled down again
Cheers
Andi
[Edit] PS: ...and the tip is reverted to the "original" state again... [/Edit]
modified 10-Apr-12 16:05pm.
|
|
|
|
|
So here I was, trying to figure out why I was having problems with my ASP RegEx validator control. The objective was to match to an IP address, but to allow it to end in "*" in the final octets (that is, 255.255.255.255 is valid, and so is 255.255.255.* or 255.255.*.* or 255.*.*.*).
But the validation was failing for 0.0.0.200, or anything over 199 in the last octet.
Here is what I had:
ValidationExpression="((1?\d?\d)|(2[0-4]\d)|(25[0-5]))\.(([*]\.[*]\.[*])|(((1?\d?\d)|(2[0-4]\d)|(25[0-5]))\.(([*]\.[*])|(((1?\d?\d)|(2[0-4]\d)|(25[0-5]))\.([*]|((1?\d?\d)|(2[0-4]\d)|(25[0-5])))))))"
Here is the fix:
ValidationExpression="((25[0-5])|(2[0-4]\d)|(1?\d?\d))\.(([*]\.[*]\.[*])|(((25[0-5])|(2[0-4]\d)|(1?\d?\d))\.(([*]\.[*])|(((25[0-5])|(2[0-4]\d)|(1?\d?\d))\.([*]|((25[0-5])|(2[0-4]\d)|(1?\d?\d)))))))"
By reversing the order (priority) of the octet matches, I solved the problem...
|
|
|
|
|
You might consider making it more readable, e.g.:
string b = @"25[0-5]|2[0-4]\d|1?\d?\d";
string n = @"(?:"+b+@")";
string w = @"(?:\*|"+b+@")";
string d = @"\.";
string ip = n+d+w+d+w+d+w;
Cheers
Andi
|
|
|
|
|
Hello,
Why
\\begin\{verbatimtab\}[\n.]*\\end\{verbatimtab\}
does not match
\begin{verbatimtab}
10 56
3 235
\end{verbatimtab}
Any help appreciated,
Greetings - Jacek
|
|
|
|
|
You generally need a modifier tacked on the end of the regex, or an extra parameter in the call to match or whatever to specify multiline input. I'm guessing your current call stops scanning at the first newline.
Sorry I can't be more specific without knowing what regex engine/language/context you're using.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
Thanks for answering!
I tried to mess around NL settings, but without success. Could you get it working here: http://www.regexplanet.com/simple/index.html[^]? I'll be fine then (hopefully).
Ultimately, I want to use it in VS find/replace dialog (Notepad++ does not support NL in regex ).
Greetings - Jacek
|
|
|
|
|
I didn't look closely at the middle of your regex. Your fragment [\n.]* matches any number of (newline or fullstop) Inside the square brackets, the fullstop is not a wildcard. That is probably not what you want. A simple .* is probably what you need if you are not interested in capturing the content, given that the multiline flag should take care of "any character" matching newline.
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994.
|
|
|
|
|
Peter_in_2780 wrote: Inside the square brackets, the fullstop is not a wildcard.
Oh, that was too easy
BUT, it would work if VS allowed to setup regex in a find/replace dialog. It is not possible though. However, the \n works. How to code that regex if . does not catch a new-line and it cannot be changed? (answer: code it yourself, but I would be nice if it wasn't necessary)
Greetings - Jacek
|
|
|
|
|
Huh, it's not very critical thing, but, unfortuantely, begun to like the research.
I have tried just now:
string replaced = Regex.Replace(all, @"\\begin\{verbatimtab\}.*\\end\{verbatimtab\}", (Match m) => (m.Value), RegexOptions.Singleline);
The SingleLine mode specs: "Specifies single-line mode. Changes the meaning of the dot (.) so it matches every character (instead of every character except \n)."
Didn't work.
Greetings - Jacek
|
|
|
|
|
Is this solved?
If not, and if you are talking about C# Regex, then the following will do:
string p = @"\\begin\{verbatimtab\}[\s\S]*?\\end\{verbatimtab\}";
Console.WriteLine("{0}", Regex.Match(str1, p).Success);
The trick:
- use
[\s\S] to match any character, independent of singleline or multiline setting - use lazy match
*? to allow multiple such groups to be matched individually
Cheers
Andi
modified 7-Apr-12 18:59pm.
|
|
|
|
|
The topic is pretty outdated -- I have done it manually for much less time than I had spent trying to build a proper regex
Thanks for a nice trick to ignore multiline settings, though.
Greetings - Jacek
|
|
|
|
|
Hi
I'm using C# and I have the regex below to split words and not split a string ".. .." instead take the whole string as on item to a List.
Example:
text="all "1 dl""
after split
all[0]="all"
all[1]="1 dl"
I found it in Google and it works, but I don't understand how it works.
string regexSpliter = @"(?<=^(?:[^""]*""[^""]*"")*[^""]*) ";
List<string> all =new List<string>_ (System.Text.RegularExpressions.Regex.Split(text, regexSpliter));
And if I remove the space before the last " in the string it doesn't work as I want. It seems like it splits all the characters in to elements written in the string text.
Can anybody please explain the string regexSplitter and why it has to be a space last in the string.
Many thanks
Fia
|
|
|
|
|
From what I can tell, that should be matching a SPACE that follows a anycharactersotherthanaquoteQUOTEanycharactersotherthanaquoteQUOTEanynumberofquotes , but you say it matches your test string so I must be misreading it.
At any rate, you can make something simpler. What exactly do you have and what do you want from it?
|
|
|
|
|
Hi
Thanks for all replies.
I'm trying to get words and if there are strings between quotes get that too that users have entered in a textbox. But I still don't understand how the string regexSplitter works. And I still don't understand why it has to be a space last in that string. Because when I remove it, it doesn't work as I want.
Thanks
Fia
|
|
|
|