I have an TEXT field in an SQLite table that is required to be exactly 17 characters long. Let's call it myfield.
For any arbitrary row in this table, how can we use SQLite's GLOB operator within a CHECK bracket to match each character in the myfield column entry (and, if possible, enforce the 17 character constraint)?
Every character in this entry can be any digit 0 - 9, or any uppercase letter excluding I, O, and Q. Also, the 9th character of the myfield entry can only be a digit 0 - 9 or the letter X, but I'm still trying to get the previous conditions first.
What have I tried?
CHECK(myfield GLOB '[A-HJ-NPR-Z0-9]{17}') - This doesn't work, and I think it's because GLOB doesn't support the curly bracket notation - correct me if I'm wrong.
CHECK(length(myfield) == 17 AND myfield GLOB '[A-HJ-NPR-Z0-9]') - Also doesn't work, presumably because the second check condition only matches a single character, contradicting the first.
I'm convinced there's a simpler solution than setting up 17 check conditions for each character in the string!
In SQLite there is a trick to emulate a function like MySql's REPEAT() which returns a string repeated n times.
So by:
REPLACE(HEX(ZEROBLOB(8)), '00', '[A-HJ-NPR-Z0-9]')
you get the string '[A-HJ-NPR-Z0-9]' repeated 8 times:
[A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9]
You can use this trick to construct (by concatenations) the string that you need after GLOB in your CHECK constraint:
CHECK(myfield GLOB
REPLACE(HEX(ZEROBLOB(8)), '00', '[A-HJ-NPR-Z0-9]') ||
'[X0-9]' ||
REPLACE(HEX(ZEROBLOB(8)), '00', '[A-HJ-NPR-Z0-9]')
)
See a simplified demo.
Simply copy and paste it for 17 times
CHECK (myfield GLOB "[A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][X0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9][A-HJ-NPR-Z0-9]")
And at the 9th element, just key in X0-9, so "the 9th character of the myfield entry can only be a digit 0 - 9 or the letter X" can be checked too
By doing this, you can also enforce the 17 characters constraint
Related
I am journeying through the Ada 2012 RM and would like to see if there is a hole in my understanding or a hole in the RM. Assuming that
put_line ("-- this is a not a comment");
is legal code, how can I deduce its legality from the RM, since section 2.7 states that "a comment starts with two adjacent hyphens and extends up to the end of the line.", while section 2.6 states "a string_literal is formed by a sequence of graphic characters (possibly none) enclosed between two
quotation marks used as string brackets." It seems like there is tension between the two sections and that 2.7 would win, but that is apparently not the case.
To get a clearer understanding here, you need to have a look at section 2.2 in the RM.
2.2 (1), which states;
The text of each compilation is a sequence of separate lexical elements. Each lexical element is formed from a sequence of characters, and is either a delimiter, an identifier, a reserved word, a numeric_literal, a character_literal, a string_literal, or a comment. The meaning of a program depends only on the particular sequences of lexical elements that form its compilations, excluding comments.
And 2.2 (3/2) which states:
"[In some cases an explicit separator is required to separate adjacent lexical elements.] A separator is any of a separator_space space character, a format_effector format effector, or the end of a line, as follows:
A separator_space space character is a separator except within a comment, a string_literal, or a character_literal.
The character whose code point position is 16#09# (CHARACTER TABULATION) Character tabulation (HT) is a separator except within a comment.
The end of a line is always a separator.
One or more separators are allowed between any two adjacent lexical elements, before the first of each compilation, or after the last."
and
A delimiter is either one of the following special characters:
& ' ( ) * + , – . / : ; < = > |
or one of the following compound delimiters each composed of two adjacent special characters
=> .. ** := /= >= <= << >> <>
Each of the special characters listed for single character delimiters is a single delimiter except if this character is used as a character of a compound delimiter, or as a character of a comment, string_literal, character_literal, or numeric_literal.
So, once you filter out the white-space of a program text and break it down into a sequence of lexical elements, a lexical element corresponding to a string literal begins with a double quote character, and a lexical element corresponding to a comment begins with --.
These are clearly different syntax items, and do not conflict with each other.
This also explains why;
X := A - -1
+ B;
gives a different result than;
X := A --1
+ B;
The space separator between the dashes makes the first minus a different lexical element than the -1, so -1 is a numeric literal in the first case, while the --1 is a comment.
I want to use sqlite3 query like this:
select * from Log where Desc glob '*[ _.,:;!?-(){}[]<>''"]OK';
to find records which ends with OK, like
OK
asdasda _OK
asda (OK
dasda [OK
dasda ]OK
but this fails me when i use back bracket in query...glob '*[ []]OK';
Any suggestions?
A comment hidden in the source code says:
Globbing rules:
* Matches any sequence of zero or more characters.
? Matches exactly one character.
[...] Matches one character from the enclosed list of characters.
[^...] Matches one character not in the enclosed list.
With the [...] and [^...] matching, a ] character can be included
in the list by making it the first character after [ or ^. A
range of characters can be specified using -. Example:
[a-z] matches any single lower-case letter. To match a -, make
it the last character in the list.
So, your records can be found with ... glob '*[] _.,:;!?(){}[<>''"-]OK'.
Updated::
Password strength:
Contain characters from three of the following four categories:
English uppercase characters (A through Z)
English lowercase characters (a through z)
Base 10 digits (0 through 9)
Non-alphabetic characters (for example, !, $, #, %
IS it possible to compare two fields value(entered) with regex...if yes then please add onr another condition to above list.
compare password with username entered they must be different
EDIT: This answer was written before the question was edited. It originally included the requirement to not include the user's account name, and be at least 8 characters long.
Given that you need to use the user's account name as part of it anyway, is there any reason you particularly want to do this as a regular expression? You may want to use regular expressions to express the patterns for the four categories (although there are other ways of doing it too) but I would write the rules out separately. For example:
// Categories is a list of regexes in this case. You could easily change
// it to anything else.
int categories = Categories.Count(regex => regex.IsMatch(password));
bool valid = password.IndexOf(name, StringComparison.OrdinalIgnoreCase) == -1
&& password.Length >= 8
&& categories >= 3;
If you need to do it in one expression it should be something like this:
^(?:(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!%,.;:])|(?=.*[a-z])(?=.*[0-9])(?=.*[!%,.;:])|(?=.*[A-Z])(?=.*[0-9])(?=.*[!%,.;:])).{8,}$
See it here on Regexr
Positive lookaheads (the (?=.*[a-z])) are used to check if the string contains the character group you want.
The problem here is, you want 3 out of 4, that means you have to make an alternation with all the allowed combinations.
The last part .{8,} is then matching the string and checking for at least 8 characters.
^ and $ are anchors, that anchor the pattern to the start and the end of the string.
[!%,.;:] is a character class, here you can add all the characters you want to include. Maybe its simpler to use a Unicode script like \p{P} for all punctuation characters. For more details see here on regular-expresssions.info
Update
compare password with username entered they must be different
normally you should be able to build up your regular expression using string concatenation. I have no idea how it is in your case where you put the regex ...
Something like this (pseudo)
String Username = "FooBar";
regex = "^(?:(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])|(?=.*[a-z])(?=.*[A-Z])(?=.*[!%,.;:])|(?=.*[a-z])(?=.*[0-9])(?=.*[!%,.;:])|(?=.*[A-Z])(?=.*[0-9])(?=.*[!%,.;:]))(?i)(?!.*" + Username + ").+$";
I used here also an inline modifier (?i) to match it case independent. The (?!.* is the start of negative lookahead, meaning the string should not contain ...
I would like to know if it is possible to use [] in SQLite query as we used to in Access and other DB.
e.g. SELECT * FROM mytable WHERE fwords like '%b[e,i,a]d%'
this will retrieve all rows have fwords containing bad, bed, bid
Thanks a lot
From http://www.sqlite.org/lang_expr.html:
The LIKE operator does a pattern matching comparison. The operand to the right of the LIKE operator contains the pattern and the left hand operand contains the string to match against the pattern. A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters in the string. An underscore ("_") in the LIKE pattern matches any single character in the string. Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching).
Does that help?
You can have a look at the regex section here.
I'm trying to write a validator for an ASP.NET txtbox.
How can I validate so the regular expression will only match if the 6th character is a "C" or a "P"?
^.{5}[CP] will match strings starting with any five characters and then a C or P.
Depending on exactly what you want, you are looking for something like:
^.{5}[CP]
The ^ says to start from the beginning of the string, the . defines any character, the {5} says that the . must match 5 times, then the [CP] says the next character must be part of the character class CP - i.e. either a C or a P.
^.{5}[CP] -- the trick is the {}, they match a certain number of characters.
^.{5}[CP] has a few important pieces:
^ = from the beginning
. = match anything
{5} = make the previous match the number of times in braces
[CP] = match any one of the specific items in brackets
so the regex spoken would be something like "from the beginning of the string, match anything five times, then match a 'C' or 'P'"
[a-zA-Z0-9]{5}[CP] will match any five characters or digits and then a C or P.