SQL pattern matching using regular expression - regex

Can we use Regex i.e, Regular Expression in SQL Server? I'm using SQL-2012 and 2014 and there is an requirement to match and return input from my stored procedure.
I can't use LIKE in this situation since like only returns matching words, Using Regex I can match whole bunch of characters like Space, Hyphen, Numbers.
Here is my SP
--Suppose XYZ P is my Search Condition
Declare #Condition varchar(50) = 'XYZ P'
CREATE PROCEDURE [dbo].[usp_MATCHNAME]
#Condition varchar(25)
as
Begin
select * from tblPerson
where UPPER(Name) like UPPER(#Condition) + '%'
-- It should return both XYZ P and xyzp
End
Here my SP is going to return all matching condition where Name=XYZ P, but how to retrieve other Column having Name as [XYZP, XYZ-P]
and if search condition have any Alphanumeric value like
--Suppose XYZ 1 is my Search Condition
Declare #Condition varchar(50) = 'XYZ 1'
Then my search result should also return nonspace value like [XYZ1, xyz1, Xyz -1].
I don't want to use Substring by finding space and splitting them based on space and then matching.
Note: My input condition i.e., #Condition can have both Space or Space less, Hyphen(-) value when executing Stored Procedure.

Use REPLACE command.
It will replace the single space into %, so it will return your expected results:
SELECT *
FROM tblPerson
WHERE UPPER(Name) LIKE REPLACE(UPPER(#Condition), ' ', '%') + '%'

Related

php doctrine createQueryBuilder special character

Database store the value "&You" but the query below doesn't return result
$buildQuery = $this->createQueryBuilder('r')
->where('r.TitreSearch LIKE :term')
->setParameter('term', "%&You%")
;
On the other hand if I search "You" I have a result
why doctrine not understand character "&" ?
The problem is not the ampersand character but the query itself.
If you want LIKE to match a pattern within the column value, you must enclose the search term with percentage signs (i.e. %term%). Without the percentage signs, LIKE acts just the same as the = operator; it looks for an exact match.
Try the following:
$term = "&You";
$buildQuery = $this->createQueryBuilder('r')
->where('r.TitreSearch LIKE :term')
->setParameter('term', "%$term%");

Autohotkey extract text using regex

I am just now learning regex using autohotkey but can't figure out how to extract specific string and save to a variable?
Line of text I am searching:
T NW CO NORWALK HUB NW 201-DS3-WLFRCTAICM5-NRWLCT02K16 [DS3 LEC] -1 -1 PSTN
I am trying to save, NW 201-DS3-WLFRCTAICM5-NRWLCT02K16 [DS3 LEC] ONLY.
Here is my regex code:
NW\D\d.DS3.]
But how do I store that as a variable in autohotkey?
I have tried RegexMatch but that only shows the position. I am doing something wrong.
You may provide the third argument that will hold the match array:
RegExMatch(str,"NW\D\d.*DS3.*\]",matches)
Then, matches[0] will contain the match.
If you use capturing groups inside the pattern, you will be able to access their values by using further indices. If you use "NW\D(\d.*DS3.*)\]" against "NW 5xxx DS3 yyy], you will have the whole string inside matches[0] and matches[1] will hold 5xxx DS3 yyy.
See AHK RegExMatch docs:
FoundPos := RegExMatch(Haystack, NeedleRegEx [, UnquotedOutputVar = "", StartingPosition = 1])
UnquotedOutputVar
Mode 1 (default): OutputVar is the unquoted name of a variable in which to store the part of Haystack that matched the entire pattern. If the pattern is not found (that is, if the function returns 0), this variable and all array elements below are made blank.
If any capturing subpatterns are present inside NeedleRegEx, their matches are stored in a pseudo-array whose base name is OutputVar. For example, if the variable's name is Match, the substring that matches the first subpattern would be stored in Match1, the second would be stored in Match2, and so on. The exception to this is named subpatterns: they are stored by name instead of number. For example, the substring that matches the named subpattern "(?P<Year>\d{4})" would be stored in MatchYear. If a particular subpattern does not match anything (or if the function returns zero), the corresponding variable is made blank.
; If you want to delete ALL ....
Only(ByRef C)
{
/*
RegExReplace
https://autohotkey.com/docs/commands/RegExReplace.htm
*/
; NW 201-DS3-WLFRCTAICM5-NRWLCT02K16 [DS3 LEC]
C:=RegExReplace(C, "NW\s[\w-]+\s\[[\w\s]+\]","",ReplacementCount,-1)
if (ReplacementCount = 0)
return C
else
return Only(C)
} ; Only(ByRef C)
string:="Line of text I am searching: T NW CO NORWALK HUB NW 201-DS3-WLFRCTAICM5-NRWLCT02K16 [DS3 LEC] -1 -1 PSTN"
Result:=Only(string)
MsgBox, % Result
MsgBox, % Only(string)

Oracle: Extract number from String

I've reviewed this question and I'm wondering my output seems to be a little skewed.
From my understanding the REGEXP_REPLACE method, takes a string that you want to replace content with, followed by a pattern to match, then anything that does not match that pattern is replaced with the substitution param.
I've written the following function to extract distance from a text field, in which a spatial query will be performed on the result.
CREATE OR REPLACE FUNCTION extract_distance
(
p_search_string VARCHAR2
)
RETURN VARCHAR2
IS
l_distance VARCHAR2(25);
BEGIN
SELECT REGEXP_REPLACE(UPPER(p_search_string), '(([0-9]{0,4}) ?MILES)', '')
INTO l_distance FROM SYS.DUAL;
RETURN l_distance;
END extract_distance;
When I run this in a block to test:
DECLARE
l_output VARCHAR2(25);
BEGIN
l_output := extract_distance('Stores selling COD4 in 400 Miles');
DBMS_OUTPUT.PUT_LINE(l_output);
END;
I'd expect the output 400 miles but in-fact I get Stores selling COD4 in. Where have I gone wrong?
"REGEXP_REPLACE extends the functionality of the REPLACE function by letting you search a string for a regular expression pattern. By default, the function returns source_char with every occurrence of the regular expression pattern replaced with replace_string." from Oracle docu
You could use, e.g.,
SELECT REGEXP_REPLACE('Stores selling COD4 in 400 Miles', '^.*?(\d+ ?MILES).*$', '\1', 1, 0, 'i') FROM DUAL;
or alternatively
SELECT REGEXP_SUBSTR('Stores selling COD4 in 400 Miles', '(\d+ ?MILES)', 1, 1, 'i') FROM DUAL;
You'll want to use, regexp_substr which returns a substring that matches the regular expression.
REGEX_SUBSTR

query for name not like other name in neo4j cypher

I'm trying to find nodes where node1's name is NOT contained in node2's name and vice versa.
I've tried this and variants of it. getting regex errors, not sure how to include the other node's literal name, and also how to do NOT includes.
START node1=node(*)
MATCH node1-[r]-node2
WHERE node1.name !~ '.*{node2.name}.*' and node2.name !~ '.*{node1.name}.*'
RETURN node1.name, node2.name limit 10;
I'll try to answer how to get your query to work, but this type of query looks a bit irregular for Neo4j. If you find yourself writing many queries like these you may want to rethink your model or choice of database.
Your '.*{node2.name}.*' contains node2.name as a string literal, not as a property reference. To resolve the property and use it's value in a regular expression you can use string concatenation, something like '.*' + node2.name + '.*'. If node2.name='Darby' then the regexp string will be '.*Darby.*'.
Regexp is signified with =~, if you want to use ! to check for property existence you can do node.property! =~ regexp. To exclude the results of your double regexp condition, do WHERE NOT ( condition1 OR condition2 ).
Since the operator order between string concatenation and regexp comparison is not obvious, it's probably best to put the string concatenation in parenthesis too, or you may end up concatenating the result of a regexp on the first string part with the rest of the string parts, i.e (node.name =~ '.*') + node2.name + '.*', which would be a type error.
Assuming you use Neo4j 1.9 the whole query could look like (for 2.0+ you can just drop the !)
START node1=node(*)
MATCH node1-[r]-node2
WHERE NOT (
node1.name! =~ ('.*' + node2.name + '.*') OR
node2.name! =~ ('.*' + node1.name + '.*')
) RETURN node1.name, node2.name LIMIT 10
(It's an expensive type of query and it probably returns redundant results, since each node pair (A,B) that fit your conditions will be returned both as (A,B) and as (B,A). Try declaring direction on the relationship, it should exclude redundant results and improve performance.)
We can use this operator "<>"
eg : match(node:Application) where node.name <> "None" return node
This query is to return all the application node whose name is not "None".

Replace using RegEx outside of text markers

I have the following sample text and I want to replace '[core].' with something else but I only want to replace it when it is not between text markers ' (SQL):
PRINT 'The result of [core].[dbo].[FunctionX]' + [core].[dbo].[FunctionX] + '.'
EXECUTE [core].[dbo].[FunctionX]
The Result shoud be:
PRINT 'The result of [core].[dbo].[FunctionX]' + [extended].[dbo].[FunctionX] + '.'
EXECUTE [extended].[dbo].[FunctionX]
I hope someone can understand this. Can this be solved by a regular expression?
With RegLove
Kevin
Not in a single step, and not in an ordinary text editor. If your SQL is syntactically valid, you can do something like this:
First, you remove every string from the SQL and replace with placeholders. Then you do your replace of [core] with something else. Then you restore the text in the placeholders from step one:
Find all occurrences of '(?:''|[^'])+' with 'n', where n is an index number (the number of the match). Store the matches in an array with the same number as n. This will remove all SQL strings from the input and exchange them for harmless replacements without invalidating the SQL itself.
Do your replace of [core]. No regex required, normal search-and-replace is enough here.
Iterate the array, replacing the placeholder '1' with the first array item, '2' with the second, up to n. Now you have restored the original strings.
The regex, explained:
' # a single quote
(?: # begin non-capturing group
''|[^'] # either two single quotes, or anything but a single quote
)+ # end group, repeat at least once
' # a single quote
JavaScript this would look something like this:
var sql = 'your long SQL code';
var str = [];
// step 1 - remove everything that looks like an SQL string
var newSql = sql.replace(/'(?:''|[^'])+'/g, function(m) {
str.push(m);
return "'"+(str.length-1)+"'";
});
// step 2 - actual replacement (JavaScript replace is regex-only)
newSql = newSql.replace(/\[core\]/g, "[new-core]");
// step 3 - restore all original strings
for (var i=0; i<str.length; i++){
newSql = newSql.replace("'"+i+"'", str[i]);
}
// done.
Here is a solution (javascript):
str.replace(/('[^']*'.*)*\[core\]/g, "$1[extended]");
See it in action