How to apply regex in javascript to obtain single quote from json - javascript

sample:
"{ ' foo ' : ' bar ' baz ' bob ' , 'foo2':'Barr ' s' }"
I want single quotes to be filtered, so that i can escape ' with \' and process.

You can use a simple str.replace() on that string to escape as follows:
"{ ' foo ' : ' bar ' baz ' bob ' , 'foo2':'Barr ' s' }".replace("'", "\'");
However, as other have stated, your json string is formatted wrong and the solution won't overall because it's only the nested single quote in 'Barr ' s' value that you want to escape. Note: regex won't be able to solve this because it can't match open closing grammar rules or the inverse.

Related

JavaScript's console.log printing unwanted characters

So basically what I'm trying to do is print a simple string to the screen using the console.log function.
Here's an example :
const fromLabel: string = '["' + "AppExp" + '"]' + '\n' + '["' + "AppExp" + '"]';
And I ultimately wanna print it, so I go:
console.log(fromLabel);
and my output is:
[\"AppExp\"]\n[\"AppExp\"]
So, basically no carriage return and unwanted '\'.
Any idea what could be the problem?
EDIT: Never mind. I was working with objects and to print them I used JSON.stringify.. little did I know I used it on this string as well ..my bad
Backslashes are escaping certain characters in the string. Your string is put together in a weird way—you're mixing "" and ''. Try this:
var str = '["' + 'AppExp' + '"]' + '\n' + '["' + 'AppExp' + '"]'
console.log(str)
try this code with template literals
I omitted the : string to be able to run the snippet but remember to add it!
const fromLabel = `[""AppExp""]
[""AppExp""]`;
console.log(fromLabel);
or in case you do not want duplicate " chars
const fromLabel: string = `["AppExp"]
["AppExp"]`;
I hope it helps! :)

Trying to print a unicode code point table

I am trying to make a unicode code points table that prints the code points till U+300
I change the number into hexadecimal and concatenate it with the unicode escape sequence.
When I try to concatenate the hexadecimal number with '\u' I get an error SyntaxError: Invalid Unicode Escape Sequence
Here's the code
How can I fix that error?
Change the print statement to print(num + ' => ' + String.fromCharCode("0x" + num));
Instead of this:
print(num + ' => ' + '\u' + num);
use this:
print(num + ' => ' + '\\u' + num);
Or, more concisely,
print(num + ' => \\u' + num);
You need to escape the \ itself to include it in a string literal.

regular expression to check only one decimal point

I have following regular expression to check only one decimal point for type number tag in html
^-?[0-9]*\\.?[0-9]*$
but this regular failed to check If I put decimal at the end e.g 12.12.
what further I have to add to check this
I think your regex can be easily fixed using a + instead of last * quantifier:
^-?[0-9]*\.?[0-9]+$
Tests:
const regex = /^-?[0-9]*\.?[0-9]+$/gm;
console.log('regex.test?')
console.log('12 = ' + regex.test('12'));
console.log('12. = ' + regex.test('12.'));
console.log('12.1 = ' + regex.test('12.1'));
console.log('12.12. = ' + regex.test('12.12.'));
console.log('-1 = ' + regex.test('-1'));
console.log('-1. = ' + regex.test('-1.'));
console.log('-1.2 = ' + regex.test('-1.2'));
console.log('-.12 = ' + regex.test('-.12'));
console.log('-. = ' + regex.test('-.'));
console.log('-. = ' + regex.test('-'));
console.log('. = ' + regex.test('.'));
Demo
Can you try the below : [1-9]\d*(\.\d+)?$
The simplest way to allow a possible . at the end is to have \.? just before the $. Also, the double \ looks wrong (unless you need it for escaping a \ in the context in which you are using it):
^-?[0-9]*\.?[0-9]*\.?$
But please recognize that your regex does not require any actual digits, so will match some non-numbers, like ., -. and (with my edit) -.. The above regex will also match an empty string!
You will want to either change your regex to require digits, or take into account somewhere else that they might not be there.

Regex find comma delimiters not in quotes AND not in parenthesis

My ultimate goal is to develop a function to convert Access IIF() statements to T-SQL (2008) CASE WHEN statments. I already have a VBA routine that finds the IIF and the matching closing parenthesis even if it is outside of quotes. It is recursive and finds nested IIF() statements without using RegEx. When I narrow down to the text inside the IIF parenthesis I need to identify the two comma delimiters that separate the three parameters. I am having trouble when a parenthesis is inside of quotes. How can I setup the RegEx to ignore anything in quotes before processing the rest of the expression?
I'm trying to create an expression group that will find anything inside single quotes and anything inside of parenthesis, then exclude anything that matches that group, and find the commas. (Please forgive me if I'm not saying this correctly since 'capturing group' and 'non-capturing group' sometimes give me the opposite of what I expect).
Note that this solution has to work with the VBScript Regular Expression support which is basically the same as the JavaScript flavor.
condition, true, false <-- this is the string my IIF parsing function returns before trying to split into 3 parts.
This is the expression that I've pieced together so far:
,(?=([^']*'[^']*')*(?![^']*'))(?![^(]*[)])
which works on this:
a=1, nz(b,0), Left('xy,z',2)
But these lines are more challenging. I can't find an expression that works on all of them.
a=1, '1st)', '(2nd)'
left(right(a,5),1)='b', '1st)', '(2nd)'
a=1, Left('a,bc',1) , 'xy,z'
Here's a Regex101 that I've been working on:
https://regex101.com/r/qH0wD8/2
The answer is, what I was trying to do was not appropriate for RegEx. Instead I solved the problem by writing a parser that handles nested parenthesis, matching quotes, and miscellaneous commas.
I hope you find this answer because you need a function to convert IIF() statements to CASE WHEN and not my complex RegEx inquiry. The main use case I have for this function is converting Access SQL to T-SQL for SQL Server 2008 and earlier. SQL Server 2012 and later support the IIF() function. You can use this VBA function in any VBA editor. You can use Excel if Access isn't handy.
Here is a VBA function to convert Access IIF() statements to T-SQL CASE WHEN statments
Public Function ReplaceIIFwithCASE(ByVal strInput As String) As String
' Parse the passed string and find the first "IIF(" and parse it into
' a standard T-SQL CASE WHEN statement. If a nested IIF is found,
' recurse and call this function again.
'
' Ben Sacherich - May 2016-Feb 2017
'
' This supports:
' IIF() embedded anywhere in the input string.
' Nested IIF() statements.
' The input string containing multiple IIF() statements on the same level.
' Strings between open and close IIF parenthesis that contains literal commas or commas for other functions.
' Example: IIF(a=1, nz(b,0) , Left('xy,z',2))
'
' Be aware:
' This does not optimize the CASE statement in places where a nested IIF could
' be written as a single CASE statement.
' It will fail if text inside IIF() containes the pipe character |. If you
' need to process statements with this character, modify this routine
' to use another temporary character for |.
'
' Try these in the Immediate window:
' ? ReplaceIIFwithCASE("IIF(a=1, nz(b,0) , Left('xy,z',2))")
' ? ReplaceIIFwithCASE("IIf(x='one',IIf(Abs(Z)=1,2,3),'three')")
' ? ReplaceIIFwithCASE("IIF(a=1,'1st)', '2nd)')")
' ? ReplaceIIFwithCASE("SELECT Name, IIF(Gender='M', 'Boy', 'Girl') FROM Students")
'
' How this works:
' Find "IIF(" in the passed string. Return original string if not found.
' Search for the matching closing parenthesis.
' When the match is found, recurse and make sure an "IIF(" is not nested.
' After recursing, replace the IIF with a CASE statement.
' - Once I find the inner part of an IIF this will use the Split function
' to delimit by commas "," into an array.
' - Then it looks at each array element. If it contains an odd number of
' single or double quote characters or different number of opening and
' closing parenthesis, it combines the array element part with the next
' part and tests again.
' - When there are matched single/double quotes and equivalent number of
' parenthesis it holds that part and appends the "|" character. This
' means that it has identified one of the 3 parameters that is passed
' to the IIF function.
' - Then it splits the string by the "|" character into three pieces
' and builds the CASE statement.
' Continue searching the passed string for another occurrence of "IIF(" (not nested).
Dim lngFuncStart As Long
Dim lngPosition As Long
Dim intStack As Integer
Dim strFunction As String
Dim strChar As String
Dim strQuoteChar As String
Dim bolInQuotes As Boolean
Dim strSplit() As String
Dim ReturnValue As String
On Error GoTo ErrorHandler
strFunction = "IIF("
strQuoteChar = "'" ' Define the style of quotes to look for and exclude.
bolInQuotes = False ' We are currently not inside quotes.
lngFuncStart = InStr(1, strInput, strFunction, vbTextCompare)
If lngFuncStart > 0 Then
lngFuncStart = lngFuncStart + Len(strFunction)
intStack = 1
lngPosition = lngFuncStart
Do While lngPosition <= Len(strInput)
' Use a WHILE loop instead of a FOR loop because the current and end positions will change inside the loop.
strChar = Mid(strInput, lngPosition, 1)
If strChar = strQuoteChar Then
bolInQuotes = Not bolInQuotes
' Move on to the next character
ElseIf bolInQuotes = False Then
' We are currently not inside quotes.
Select Case strChar
Case ")"
' Closing a group
intStack = intStack - 1
Case "("
' Starting new group
intStack = intStack + 1
End Select
If intStack = 0 Then ' Found closing parenthesis.
' See if there is a nested match. ### Recursive ###
ReturnValue = ReplaceIIFwithCASE(Mid(strInput, lngFuncStart, lngPosition - lngFuncStart))
' Begin parsing commas.
strSplit() = Split(ReturnValue, ",")
Dim strPart As String
Dim strRebuilt As String
Dim i As Integer
strRebuilt = ""
If UBound(strSplit()) > 2 Then ' There are more than 2 commas. Piece together the parts.
strPart = strSplit(0)
For i = 1 To UBound(strSplit)
If UBound(Split(strPart, "'")) Mod 2 = 0 _
And UBound(Split(strPart, """")) Mod 2 = 0 _
And UBound(Split(strPart, "(")) = UBound(Split(strPart, ")")) Then
' Number of single quotes is Even or Zero (matched)
' Number of double quotes is Even or Zero (matched)
' Number of parenthesis is matched
' Add the "|" symbol where the IIF should have commas.
strRebuilt = strRebuilt & "|" & strPart
strPart = strSplit(i)
Else
strPart = strPart & "," & strSplit(i)
End If
Next
ReturnValue = Mid(strRebuilt & "|" & strPart, 2)
strSplit() = Split(ReturnValue, "|")
End If
If UBound(strSplit) = 2 Then
' IIF has 3 parameters and is the normal case.
'--- Replace the IIF statement with CASE WHEN ---
' CASE statement help: https://msdn.microsoft.com/en-us/library/ms181765.aspx
ReturnValue = "(CASE WHEN " & Trim(strSplit(0)) & " THEN " & Trim(strSplit(1)) & " ELSE " & Trim(strSplit(2)) & " END)"
'ReturnValue = "(CASE WHEN...)"
If Right(Mid(strInput, 1, lngFuncStart - Len(strFunction) - 1), 2) = vbCrLf Then
' Don't bother to add a CrLf
Else
' Add a CrLf before the CASE statement to make identification easier.
' Comment this out if you don't want it added.
ReturnValue = vbCrLf & ReturnValue
End If
strInput = Mid(strInput, 1, lngFuncStart - Len(strFunction) - 1) & ReturnValue & Mid(strInput, lngPosition + 1)
Else
' Something is wrong. Return the original IIF statement.
' Known issues:
' Text inside IIF() contained pipe character |
' Text contained unmatched parenthesis, maybe inside of a literal string like '1st)'
ReturnValue = "IIF(" & ReturnValue & ") /*### Unable to parse IIF() ###*/ "
strInput = Mid(strInput, 1, lngFuncStart - Len(strFunction) - 1) & ReturnValue & Mid(strInput, lngPosition + 1)
End If
'--- Check to see if there is another function call following the one just addressed. ---
lngFuncStart = InStr(lngFuncStart + Len(ReturnValue) - Len(strFunction), strInput, strFunction, vbTextCompare)
If lngFuncStart > 0 Then
' Another IIF function call is at the same level as the one just processed.
lngFuncStart = lngFuncStart + Len(strFunction)
intStack = 1
lngPosition = lngFuncStart
Else
ReturnValue = strInput
Exit Do
End If
End If
End If
lngPosition = lngPosition + 1
Loop
Else
' Function not found in passed string.
ReturnValue = strInput
End If
ReplaceIIFwithCASE = ReturnValue
Exit Function
ErrorHandler:
MsgBox "Error #" & Err.Number & " - " & Err.Description & vbCrLf & "in procedure ReplaceIIFwithCASE()" _
& vbCrLf & "Input: " & strInput, vbExclamation, "Error"
End Function
You can use recursive matching:
(?>(?>\([^()]*(?R)?[^()]*\))|(?>'[^']*')|(?>[^()' ,]+))+
The outer match is allowed to be repeated (?>...)+. Inside, there are three options. The first one matches balanced ():
(?>\([^()]*(?R)?[^()]*\)
The second matches anything between single quotes '...':
(?>'[^']*')
The third matches anything except (), or ', or comma, or space:
(?>[^()' ,]+)

Why does this regex/DOM character entity tester return `undefined`?

var str = 'let us pretend that this is a blog about gardening&cooking; here&apos;s an apostrophe & ampersand just for fun.';
This is the string I'm operating on. The desired end result is: "let us pretend that this is a blog about gardening&cooking; here&apos;s an apostrophe & ampersand just for fun."
console.log('Before: ' + str);
str = str.replace(/&(?:#x?)?[0-9a-z]+;?/gi, function(m){
var d = document.createElement('div');
console.log(m);
d.innerHTML = m.replace(/&/, '&');
console.log(d.innerHTML + '|' + d.textContent);
return !!d.textContent.match(m.replace(/&/, '&')[0]) ? m : d.textContent;
});
console.log('After: ' + str);
The problem is that HTML doesn't support XML's &apos;
To avoid the issue you should use ' instead of &apos;
For more information look at this post:
Why shouldn't &apos; be used to escape single quotes?
This should do what you want:
str.replace(/&([#x]\d+;|[a-z]+;)/g, "&$1")
or, with a positive lookahead:
str.replace(/&(?=[#x]\d+;|[a-z]+;)/g, "&")
I don't think you need any HTML2text en-/decoding.

Categories