I have googled this ane are really surprised not to find a ready made solution to this as I believe that it is a problem that is faced by anyone who is updating databases from forms.
Problem is the single quote that is used in text fields as an apostrophe and other instances.
So I need to find are replace all occurrences of single quotes within an SQL statement in Javascript / Nodejs before sending it to the database, this of course is not a hard-coded statement and it will be different every time, but the following includes carriage returns in the sql statement as well as spaces before and after an equal sign as well as no spaces to try and catch all occurrences.
The key thing really is the "=" followed by a single speech mark, the text to grab and the closing single speech mark followed by a space, a comma, or the word "WHERE".
I am no expert with regex, but have come up with this, which only correctly extracts a couple of the strings:
/\= *'(.*)' *[, *]/g
Would appreciate help from any of the regex experts out there :-)
update XXX set status = 'Pending's' where xx = 'xxx'
UPDATE XX_XXX
SET
SUBJECT='Test of system's', SERIAL_NUMBER='SN'1'23', SPEC='Verify order's package is complete',
DESCRIPTION='13.3/8'' Buttress Pin's ' WHERE ID='1002-15'
This should be the result:
update XXX set status = 'Pending''s' where xx = 'xxx'
UPDATE XX_XXX
SET
SUBJECT='Test of system''s', SERIAL_NUMBER='SN''1''23', SPEC='Verify order''s package is complete',
DESCRIPTION='13.3/8''' Buttress Pin''s ' WHERE ID='1002-15'
And these are the strings that need to be selected:
Pending's
Test of system's
SN'1'23
Verify order's package is complete
13.3/8'
1002-15
It is very common issue, do not need regex. Just simply replace a single quote in a string to double single quote.
This is example. Just see the comment
--This is double quote I used, because ally's wonderland not work at here.
DECLARE #StringValueWithSingleQuote varchar( 50) = 'Ally''s wonderland'
-- just see the magid, replace double single quote to single quote while displaing
select #StringValueWithSingleQuote
--This is actual you have to do
select REPLACE( #StringValueWithSingleQuote , char(39) , Char(39)+Char(39) )
Related
I am trying to insert some text data into a table in SQL Server 9.
The text includes a single quote '.
How do I escape that?
I tried using two single quotes, but it threw me some errors.
eg. insert into my_table values('hi, my name''s tim.');
Single quotes are escaped by doubling them up, just as you've shown us in your example. The following SQL illustrates this functionality. I tested it on SQL Server 2008:
DECLARE #my_table TABLE (
[value] VARCHAR(200)
)
INSERT INTO #my_table VALUES ('hi, my name''s tim.')
SELECT * FROM #my_table
Results
value
==================
hi, my name's tim.
If escaping your single quote with another single quote isn't working for you (like it didn't for one of my recent REPLACE() queries), you can use SET QUOTED_IDENTIFIER OFF before your query, then SET QUOTED_IDENTIFIER ON after your query.
For example
SET QUOTED_IDENTIFIER OFF;
UPDATE TABLE SET NAME = REPLACE(NAME, "'S", "S");
SET QUOTED_IDENTIFIER ON;
-- set OFF then ON again
How about:
insert into my_table values('hi, my name' + char(39) + 's tim.')
Many of us know that the Popular Method of Escaping Single Quotes is by Doubling them up easily like below.
PRINT 'It''s me, Arul.';
we are going to look on some other alternate ways of escaping the single quotes.
1. UNICODE Characters
39 is the UNICODE character of Single Quote. So we can use it like below.
PRINT 'Hi,it'+CHAR(39)+'s Arul.';
PRINT 'Helo,it'+NCHAR(39)+'s Arul.';
2. QUOTED_IDENTIFIER
Another simple and best alternate solution is to use QUOTED_IDENTIFIER.
When QUOTED_IDENTIFIER is set to OFF, the strings can be enclosed in double quotes.
In this scenario, we don’t need to escape single quotes.
So,this way would be very helpful while using lot of string values with single quotes.
It will be very much helpful while using so many lines of INSERT/UPDATE scripts where column values having single quotes.
SET QUOTED_IDENTIFIER OFF;
PRINT "It's Arul."
SET QUOTED_IDENTIFIER ON;
CONCLUSION
The above mentioned methods are applicable to both AZURE and On Premises .
2 ways to work around this:
for ' you can simply double it in the string, e.g.
select 'I''m happpy' -- will get: I'm happy
For any charactor you are not sure of: in sql server you can get any char's unicode by select unicode(':') (you keep the number)
So this case you can also select 'I'+nchar(39)+'m happpy'
The doubling up of the quote should have worked, so it's peculiar that it didn't work for you; however, an alternative is using double quote characters, instead of single ones, around the string. I.e.,
insert into my_table values("hi, my name's tim.");
Also another thing to be careful of is whether or not it is really stored as a classic ASCII ' (ASCII 27) or Unicode 2019 (which looks similar, but not the same). This isn't a big deal on inserts, but it can mean the world on selects and updates. If it's the unicode value then escaping the ' in a WHERE clause (e.g where blah = 'Workers''s Comp') will return like the value you are searching for isn't there if the ' in "Worker's Comp" is actually the unicode value.If your client application supports free-key, as well as copy and paste based input, it could be Unicode in some rows, and ASCII in others!
A simple way to confirm this is by doing some kind of open ended query that will bring back the value you are searching for, and then copy and paste that into notepad++ or some other unicode supporting editor. The differing appearance between the ascii value and the unicode one should be obvious to the eyes, but if you lean towards the anal, it will show up as 27 (ascii) or 92 (unicode) in a hex editor.
The following syntax will escape you ONLY ONE quotation mark:
SELECT ''''
The result will be a single quote. Might be very helpful for creating dynamic SQL :).
Double quotes option helped me
SET QUOTED_IDENTIFIER OFF;
insert into my_table values("hi, my name's tim.");
SET QUOTED_IDENTIFIER ON;
This should work
DECLARE #singleQuote CHAR
SET #singleQuote = CHAR(39)
insert into my_table values('hi, my name'+ #singleQuote +'s tim.')
Just insert a ' before anything to be inserted. It will be like a escape character in sqlServer
Example:
When you have a field as, I'm fine.
you can do:
UPDATE my_table SET row ='I''m fine.';
I had the same problem, but mine was not based of static data in the SQL code itself, but from values in the data.
This code lists all the columns names and data types in my database:
SELECT DISTINCT QUOTENAME(COLUMN_NAME),DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS
But some column names actually have a single-quote embedded in the name of the column!, such as ...
[MyTable].[LEOS'DATACOLUMN]
To process these, I had to use the REPLACE function along with the suggested QUOTED_IDENTIFIER setting. Otherwise it would be a syntax error, when the column is used in a dynamic SQL.
SET QUOTED_IDENTIFIER OFF;
SET #sql = 'SELECT DISTINCT ''' + #TableName + ''',''' + REPLACE(#ColumnName,"'","''") + ...etc
SET QUOTED_IDENTIFIER ON;
The STRING_ESCAPE funtion can be used on newer versions of SQL Server
This should work: use a back slash and put a double quote
"UPDATE my_table SET row =\"hi, my name's tim.\";
I hope its just something i'm not doing right.
I've been using a simple script to create a form out of a spreadsheet. The script seems to be working fine. The output form is going to get some inputs from third parties so i can analyze them in my consulting activity.
Creating the form was not a big deal, the structure is good to go. However, after having the form creator script working, i've started working on its validations, and that's where i'm stuck at.
For text validations, i will need to use specific Regexes. Many of the inputs my clients need to give me are going to be places' and/or people's names, therefore, i should only allow them usign A-Z, single spaces, apostrophes and dashes.
My resulting regexes are:
//Regex allowing a **single name** with the first letter capitalized and the occasional use of "apostrophes" or "dashes".
const reg1stName = /^[A-Z]([a-z\'\-])+/
//Should allow (a single name/surname) like Paul, D'urso, Mac'arthur, Saint-Germaine ecc.
//Regex allowing **composite names and places names** with the first letter capitalized and the occasional use of "apostrophes" or "dashes". It must avoid double spaces, however.
const regNamesPlaces = /^[^\s]([A-Z]|[a-z]|\b[\'\- ])+[^\s]$/
//This should allow (names/surnames/places' names) like Giulius Ceasar, Joanne D'arc, Cosimo de'Medici, Cosimo de Medici, Jean-jacques Rousseau, Firenze, Friuli Venezia-giulia, L'aquila ecc.
Further in the script, these Regexes are called as validation pattern for the forms text items, in accordance with each each case.
//Validation for single names
var val1stName = FormApp.createTextValidation()
.setHelpText("Only the person First Name Here! Use only (A-Z), a single apostrophe (') or a single dash (-).")
.requireTextMatchesPattern(reg1stName)
.build();
//Validation for composite names and places names
var valNamesPlaces = FormApp.createTextValidation()
.setHelpText(("Careful with double spaces, ok? Use only (A-Z), a single apostrophe (') or a single dash (-)."))
.requireTextMatchesPattern(regNamesPlaces)
.build();
Further yet, i have a "for" loop that creates the form based on the spreadsheets fields. Up to this point, things are working just fine.
for(var i=0;i<numberRows;i++){
var questionType = data[i][0];
if (questionType==''){
continue;
}
else if(questionType=='TEXTNamesPlaces'){
form.addTextItem()
.setTitle(data[i][1])
.setHelpText(data[i][2])
.setValidation(valNamesPlaces)
.setRequired(false);
}
else if(questionType=='TEXT1stName'){
form.addTextItem()
.setTitle(data[i][1])
.setHelpText(data[i][2])
.setValidation(val1stName)
.setRequired(false);
}
The problem is when i run the script and test the resulting form.
Both validations types get imported just fine (as can be seen in the form's edit mode), but when testing it in preview mode i get an error, as if the Regex wasn't matching (sry the error message is in portuguese, i forgot to translate them as i did with the code up there):
A screenshot of the form in edit mode
A screeshot of the form in preview mode
However, if i manually remove the bars out of this regex "//" it starts working!
A screenshot of the form in edit mode, Regex without bars
A screenshot of the form in preview mode, Regex without bars
What am i doing wrong? I'm no professional dev but in my understanding, it makes no sense to write a Regex without bars.
If this is some Gforms pattern of reading regexes, i still need all of this to be read by the Apps script that creates this form after all. If i even try to pass the regex without the bars there, the script will not be able to read it.
const reg1stName = ^[A-Z]([a-z\'])+
const regNamesPlaces = ^[^\s]([A-Z]|[a-z]|\b[\'\- ])+[^\s]$
//Can't even be saved. Returns: SyntaxError: Unexpected token '^' (line 29, file "Code.gs")
Passing manually all the validations is not an option. Can anybody help me?
Thanks so much
This
/^[A-Z]([a-z\'\-])+/
will not work because the parser is trying to match your / as a string literal.
This
^[A-Z]([a-z\'\-])+
also will not work, because if the name is hyphenated, you will only match up to the hyphen. This will match the 'Some-' in 'Some-Name', for example. Also, perhaps you want a name like 'Saint John' to pass also?
I recommend the following :)
^[A-Z][a-z]*[-\.' ]?[A-Z]?[a-z]*
^ anchors to the start of the string
[A-Z] matches exactly 1 capital letter
[a-z]* matches zero or more lowercase letters (this enables you to match a name like D'Urso)
[-\.' ]? matches zero or 1 instances of - (hyphen), . (period), ' (apostrophe) or a single space (the . (period) needs to be escaped with a backslash because . is special to regex)
[A-Z]? matches zero or 1 capital letter (in case there's a second capital in the name, like D'Urso, St John, Saint-Germaine)
I'm building and inventory system and I'm trying to insert some data into MySql and noticed that I get errors when trying to insert things such as 1" Monitor Cable, or anything with quotation marks for that matter. Things such as part description and the part name could all potentially contain quotation marks or apostrophes.
I know that I can just put a "\" before the quotation marks or apostrophe's by using javascript's replace method, but I'm not sure what that would look like. If anyone could help me out, that would be great!
I assume that you process some sql in node.js and its parts are not directly copied from user input (this will be danger/unsafe) but first you filter input to prevent sql injection - if yes then try
let str = '1" Monitor Cable'
console.log( str.replace(/"/g,'\\"') );
I am passing value dynamically to javascript function.
I am retrieving data from database and filling to javascript function, it does not have a static binding.
share_it(data_from_mysql_database);
like
share_it('value from mysql database');
Some times value contain a single quote (').
like:
share_it(' Essentially you'll have to have a good academic history ');
So function call gives error that:
Uncaught SyntaxError: Unexpected identifier
You can use the \ character to escape such characters:
share_it(' Essentially you\'ll have to have a good past academic ');
Or, you can switch to using double quotes if you know you will need to embed a single quote character:
share_it(" Essentially you'll have to have a good past academic ");
You can freely switch between double " and single ' quotes where you need the other in a literal string:
share_it(" Essentially you'll have to have a good past academic ");
Only in cases where you need both, you need to escape the repeating character:
share_it(" Essentially you'll have to have a good \"past\" academic ");
You can also replace the ' in the string with '.
You ought to be converting special chars on the upstream rather than the downstream. Converting it on the upstream saves time later when an inexperienced developer does not care to escape the data on the downstream when sent to the client. Since you have not properly converted the data on the upstream, you have no choice. You should escape it.
share_it(escape(data_from_mysql_database));
Example"
> escape("You're awesome");
'You%27re%20awesome'
>
I've researched stackoverflow and find similar results but it is not really what I wanted.
Given an xml string: "<a b=\"c\"></a>" in javascript context, I want to create a regex that will capture the attribute value including the quotation marks.
NOTE: this is similar if you're using single quotation marks.
Currently I have a regular expression tailored to the XML specification:
[_A-Za-z][\w\.\-]*(?:=\"[^\"]*\")?
[_A-Za-z][\w\.\-]* //This will match the attribute name.
(?:=\"[^\"]*\")? //This will match the attribute value.
\"[^\"]*\" //This part concerns me.
My question now is, what if the xml string looks like this:
<shout statement="Hi! \"Richeve\"."></shout>
I know this is a dumb question to ask but I just want to capture rare cases that this scenario might happen (I know the coder can use single quotes on this scenario) but there are cases that we don't know the current value of the attribute given that the attribute value changes dynamically at runtime.
So to make this clearer, the result of that using the correct regex should be:
"Hi! \"Richeve\"."
I hope my question is clear. Thanks for all the help!
PS: Note that the language context is Javascript and I know it is tempting to use lookbehinds but currently lookbehinds are not supported.
PS: I know it is really hard to parse XML but I have an elegant solution to this :) so I just need this small problem to be solved. So this problem only main focus is capturing quotation marked string tokens containing quotation marks inside the string token.
The standard pattern for content with matching delimiters and embedded escaped delimiters goes like this:
"[^"\\]*(?:\\.[^"\\]*)*"
Ignoring the obvious first and last characters in the pattern, here's how the rest of the pattern works:
[^"\\]*: Consume all characters until a delimiter OR backslash (matching Hi! in your example)
(?:\\.[^"\\]*)* Try to consume a single escaped character \\. followed by a series of non delimiter/backslash characters, repeatedly (matching \"Richeve first and then \". next in your example)
That's it.
You can try to use a more generic delimiter approach using (['"]) and back references, or you can just allow for an alternate pattern with single quotes like so:
("[^"\\]*(?:\\.[^"\\]*)*"|'[^'\\]*(?:\\.[^'\\]*)*')
Here's another description of this technique that might also help (see the section called Strings): http://www.regular-expressions.info/examplesprogrammer.html
Description
I'm pretty really sure embedding double quotes inside a double quoted attribute value is not legal. You could use the unicode equivalent of a double quote \x22 inside the value.
However to answer the question, this expression will:
allow escaped quotes inside attribute values
capture the attribute statement 's value
allow attributes to appear in any order inside the tag
will avoid many of the edge cases which will trip up pattern matching inside html text
doesn't use lookbehinds
<shout\b(?=\s)(?=(?:[^>=]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*?\sstatement=(['"])((?:\\['"]|.)*?)\1(?:\s|\/>|>))(?:[^>=]|='(?:[^']|\\')*'|="(?:[^"]|\\")*"|=[^'"][^\s>]*)*>.*?<\/shout>
Example
Pretty Rubular
Ugly RegexPlanet set to Javascript
Sample Text
Note the difficult edge case in the first attribute :)
<shout onmouseover=' statement="He said \"I am Inside the onMouseOver\" " ; if ( 6 > a ) { funRotate(statement) } ; ' statement="Hi! \"Richeve\"." title="sometitle">SomeString</shout>
Matches
Group 0 gets the entire tag from open to close
Group 1 gets the quote surrounding the statement attribute value, this is used to match the closing quote correctly
Group 2 gets the statement attribute value which may include escaped quotes like \" but not including the surrounding quotes
[0][0] = <shout onmouseover=' statement="He said \"I am Inside the onMouseOver\" " ; if ( 6 > a ) { funRotate(statement) } ; ' statement="Hi! \"Richeve\"." title="sometitle">SomeString</shout>
[0][1] = "
[0][2] = Hi! \"Richeve\".