I have a tcl variable $value that is being passed through a hidden input field.
What would be a good regular expression to get it checked for an SQL injection.
I would want it to allow only numbers in case.
I would want it to allow only characters in another case.
And numbers and characters both in another case.
In all 3 cases I do not want any special chracters to be included
switch $case {
case1 {set regex {^[[:digit:]]+$}}
case2 {set regex {^[[:alpha:]]+$}}
case3 {set regex {^[[:alnum:][:space:]]+$}}
default {error "what case is this?"}
}
if {! [regexp $regex $value]} {
error "invalid value: value"
}
To remove non-matching chars
switch $case {
case1 {set regex {\D}}
case2 {set regex {[^[:alpha:]]}}
case3 {set regex {[^[:alnum:][:space:]]}}
}
set safe_value [regsub -all $regex $value ""]
See Tcl man pages for regexp, regsub, and re_syntax
Related
Lets say I have switch statement like so:
$NewName = "test.psd"
switch -RegEX ($NewName) {
"^\..*" { #if string starts with "." it means only change extension
'Entry Starts with a "."'
}
".*\..*" { # "." is in the middle , change both basename and extension
'Entry does not start with a "."'
}
"[^.]" { # if no "." at all, it means only change base name
'No "." present'
}
}
The first and second condidtions work as expected, but the last one always triggers. It will trigger against:
$NewName = "test.psd"
$NewName = ".psd"
$NewName = "test"
Doesnt regex "[^.]" mean if there is a dot, dont match. Essentially only trigger in the absence of a dot.
My expected outcome is for the last statement to only trigger if there is not dot present.
Any help on this, would be wellcome.
That would only work if "." were the only character. All the other characters would match it. You would have to repeat that pattern for every character on the line. See also Regex - Does not contain certain Characters
'a.' -match '^[^.]+$'
False
'ab' -match '^[^.]+$'
True
The dot is a special character in regular expressions, and needs to be escaped when you want to use a literal dot. Try "[^\.]" for the regular expression in the third case.
I am having trouble with matching a string with a dollar sign ($) in it.
Here is my code:
if (index($ln, '$COMB') != -1)
{
[do some stuff]
}
I have tried '\$COMB', '\\$COMB' and '\\\$COMB'
I need to match the exact string, $COMB. The problem is that my code also matches : $[some other stuff]COMB. Which is not what I want.
Indeed, index checks if a string is contained in another. It won't find $COMB in $..COMB as you claim, but it would find it in ...$COMB....
If you want to check if a string is the same as another, use eq.
$ln eq '$COMB'
For example,
$ perl -e'
CORE::say qq{"$_" is }.( $_ eq "abc" ? "equal" : "not equal" ).qq{ to "abc"}
for qw( abc abcdef def );
'
"abc" is equal to "abc"
"abcdef" is not equal to "abc"
"def" is not equal to "abc"
This is a very basic question but I am not able to find any proper documentation explaining this behaviour.
("Johnson" =~ /son/ ) returns true but (/son/ =~ "Johnson") returns false. What is the exact reason? Why =~ operator behaves differently when the operands are interchanged?
STRAIGHT OUTTA DOCS:
The simplest regexp is simply a word, or more generally, a string of
characters. A regexp consisting of a word matches any string that
contains that word:
"Hello World" =~ /World/; # matches
What is this Perl statement all about? "Hello World" is a simple double-quoted string. World is
the regular expression and the // enclosing /World/ tells Perl to
search a string for a match. The operator =~ associates the string
with the regexp match and produces a true value if the regexp matched,
or false if the regexp did not match. In our case, World matches the
second word in "Hello World" , so the expression is true.
Please read http://perldoc.perl.org/perlretut.html
Now in your example "Johnson" =~ /son/ matches because RHS of =~ (which is son) is found in LHS (Johnson). In case of /son/ =~ "Johnson" RHS (Johnson) is not found in LHS (son).
Well... because the =~ operator binds a scalar expression, to a pattern match.
So it states the order in which the arguments need to be given. Your second (/son/ =~ "Johnson") uses Johnson as pattern... and that one is not hit, thus false.
See binding operators: https://users.cs.cf.ac.uk/Dave.Marshall/PERL/node87.html
I am trying to find a pattern using perl. But I am only interested with the beginning and the end of the pattern. To be more specific I have a sequence of letters and I would like to see if the following pattern exists. There are 23 characters. And I'm only interested in the beginning and the end of the sequence.
For example I would like to extract anything that starts with ab and ends with zt. There is always
So it can be
abaaaaaaaaaaaaaaaaaaazt
So that it detects this match
but not
abaaaaaaaaaaaaaaaaaaazz
So far I tried
if ($line =~ /ab[*]zt/) {
print "found pattern ";
}
thanks
* is a quantifier and meta character. Inside a character class bracket [ .. ] it just means a literal asterisk. You are probably thinking of .* which is a wildcard followed by the quantifier.
Matching entire string, e.g. "abaazt".
/^ab.*zt$/
Note the anchors ^ and $, and the wildcard character . followed by the zero or more * quantifier.
Match substrings inside another string, e.g. "a b abaazt c d"
/\bab\S*zt\b/
Using word boundary \b to denote beginning and end instead of anchors. You can also be more specific:
/(?<!\S)ab\S*zt(?!\S)/
Using a double negation to assert that no non-whitespace characters follow or precede the target text.
It is also possible to use the substr function
if (substr($string, 0, 2) eq "ab" and substr($string, -2) eq "zt")
You mention that the string is 23 characters, and if that is a fixed length, you can get even more specific, for example
/^ab.{19}zt$/
Which matches exactly 19 wildcards. The syntax for the {} quantifier is {min, max}, and any value left blank means infinite, i.e. {1,} is the same as + and {0,} is the same as *, meaning one/zero or more matches (respectively).
Just a * by itself wont match anything (except a literal *), if you want to match anything you need to use .*.
if ($line =~ /^ab.*zt$/) {
print "found pattern ";
}
If you really want to capture the match, wrap the whole pattern in a capture group:
if (my ($string) = $line =~ /^(ab.*zt)$/) {
print "found pattern $string";
}
what does Perl's /m modifier means from this example?
For example, let say I have the following information in the Example.txt text file. And each line ends with the newline character with a data record of Data
The input record separator is set to:
$/="__Data__";
Example.txt
__Data__
This is test A.\n
This is test B.\n
This is test C.\n
This is test D.\n
Question 1, after changing the input record separator to Data, would the ^ and $ characters be position as follow?
^__Data__
This is test A.\n
This is test B.\n
This is test C.\n
This is test D.\n$
Question 2, let say I use the /m modifier while having the input record separator still set to Data, would the ^ and $ characters be set to the following?
^__Data__$
^This is test A.\n$
^This is test B.\n$
^This is test C.\n$
^This is test D.\n$
if(/__Data__/m)
{
print;
}
/$/ is not affected by $/.
Without /m,
/^/ matches the starts of the string. (/(?-m:^)/ ⇔ /\A/)
/$/ matches at the end of the string, and before a newline at the end of the string. (/(?-m:$)/ ⇔ /\Z/ ⇔ /(?=\n\z)|\z/)
^__Data__\n "^" denotes where /(?-m:$)/ can match
This is test A.\n "$" denotes where /(?-m:$)/ can match
This is test B.\n
This is test C.\n
This is test D.$\n$
With /m,
/^/ matches the starts of the string and after a "\n". (/(?m:^)/ ⇔ /\A|(?<=\n)/)
/$/ matches before a newline and at the end of the string. (/(?m:$)/ ⇔ /(?=\n)|\z/)
^__Data__$\n "^" denotes where /(?m:^)/ can match
^This is test A.$\n "$" denotes where /(?m:$)/ can match
^This is test B.$\n
^This is test C.$\n
^This is test D.$\n$
I was asked about
...$\n$
First, let's demonstrate:
>perl -E"say qq{abc\n} =~ /abc$/ ? 1 : 0"
1
>perl -E"say qq{abc\n} =~ /abc\n$/ ? 1 : 0"
1
The point is to allow /^abc$/ to match both "abc\n" and "abc".
>perl -E"say qq{abc\n} =~ /^abc$/ ? 1 : 0"
1
>perl -E"say qq{abc} =~ /^abc$/ ? 1 : 0"
1
Your assumption is correct, multiline causes ^ and $ to match the beginning and end of the string, whereas without it you match between newlines (and string ends).