What is the Regex for Only One # Character? - php

I am looking for a Regex to use in PHP in order to match one character; the # symbol.
For example, if I typed: P#ssword into an input, the Regex will match. If I typed P##ssword into an input, the regex will not match.
Here is my PHP Code that I am using:
<?php
session_start();
if($_SERVER['REQUEST_METHOD'] == "POST") {
$conn=mssql_connect('d','dd','d');
mssql_select_db('d',$conn);
if(! $conn )
{
die('Could not connect: ' . mssql_get_last_message());
}
$username = ($_POST['username']);
$password = ($_POST['password']);
if (preg_match("[\W]",$_POST["password"]))
{
if (!preg_match("^[^#]*#[^#]*$",$_POST["password"]))
{
header("location:logingbm.php");
} else {
}
}
if(!filter_var($_POST['username'], FILTER_VALIDATE_EMAIL))
{
if ($_POST["username"])
{
if ($_POST["password"])
{
$result = mssql_query("SELECT * FROM staffportal WHERE email='".$username."' AND
password='".$password."'");
if(mssql_num_rows($result) > 0) {
$_SESSION['staff_logged_in'] = 1;
$_SESSION['username'] = $username;
}}}} else {
if ($_POST["password"])
{
$result = mssql_query("SELECT * FROM staffportal WHERE email='".$username."' AND
password='".$password."'");
if(mssql_num_rows($result) > 0) {
$_SESSION['staff_logged_in'] = 1;
$_SESSION['username'] = $username;
}}}}
if(!isset($_SESSION['staff_logged_in'])) {
header("location:logingbm.php");
echo "<script>alert('Incorrect log-in information!');</script>";
} else {
header("location:staffportal.php");
}
?>

Other lightweight approaches...
Without regex
Just use substr_count (see demo)
<?php
$str1 = "pa#s#s";
$str2 = "pa#ss";
echo (substr_count($str1,"#")==1)?"beauty\n":"abject\n"; // abject
echo (substr_count($str2,"#")==1)?"beauty\n":"abject\n"; // beauty
With regex
EDIT: just saw that Sam wrote something equivalent.
If you want to use regex, you could use this fairly simple regex:
#
How? This code (see demo)
<?php
$str1 = "pa#s#s";
$str2 = "pa#ss";
$regex = "~#~";
echo (preg_match_all($regex,$str1,$m)==1)?"beauty\n":"abject\n"; // abject
echo (preg_match_all($regex,$str2,$m)==1)?"beauty\n":"abject\n"; // beauty

The easiest way would be to use the return value of preg_match_all().
Returns the number of full pattern matches (which might be zero), or FALSE if an error occurred.
Example:
$count = preg_match_all('/#/', $password, $matches);
Non regex solution (based off of #cdhowie's comment):
$string = 'P#ssword';
$length = strlen($string);
$count = 0;
for($i = 0; $i < $length; $i++) {
if($string[$i] === '#') {
$count++;
}
}
This works because you can access characters of Strings as you would with normal arrays ($var = 'foo'; $var[0] = 'f';).

As I said in my comment, your pattern needs delimiters /, #, ~ or whatever you want (see the PHP doc for that and test yourself).
To be quickly sure that a string contains only one #, you can do that:
if (preg_match('~\A[^#]*#[^#]*\z~', $yourstr))
echo 'There is one #';
else
echo 'There is more than one # or zero #';

This regexp will do what you want:
^[^#]*#[^#]*$
This matches any line that contains one and only one #.
Explanation
^ matches the beginning of the line
[^#]* matches everything before the #
# matches the # character
[^#]* matches everything after the #
$ matches the end of the line
Use
preg_match("#^[^#]*#[^#]*$#", $passwd); //Matches $passwd if it contains only one character

Here's what your regex code means:
If there is at least one non-word character in the string ([\W]), there must be exactly one at-sign (#). There may be any number of any other characters before and after the at-sign: letters, digits, control characters, punctuation, anything. Anything but #.
What I'm wondering is, are you trying to say there can be not more than one at-sign (i.e. zero or one?) That's pretty simple, conceptually; just get rid of the first regex check ("[\W]") and change the second regex to this:
"^[^#]*(?:#[^#]*)?$"
In other words:
Start by consuming not at-signs you see. If you see a #, go ahead and consume it, then resume matching whatever not at-signs remain. If that doesn't leave you at the end of the string, it can only mean there were more than one #. Abandon the attempt immediately and report a failed match.
Of course, this still leaves you with the problem of which other characters you want to allow. I'm pretty sure [^#]* is not what you want.
Also, "[\W]" may be working as you intended, but it's only by accident. You could have written it "/\W/" or "~\W~" "(\W)" and it would work just the same. You may have meant those square brackets to form a character class, but they're not even part of the regex; they're the regex delimiters.
So why did it work, you ask? \W is a predefined character class, equivalent to [^\w]. You can use it inside a regular character class, but it works fine on its own.

Related

How to check if more than one space or beginning has space in PHP

Hello World
Hello World
hello world
or if the very beginning has space
Hello World
It works if $q has normal values but I am getting $q value from search input and so it does not work except case 1.
$q = Input::get('q');
if(preg_match("/^\s+/", $q) || preg_match("/\s{2,}/", $q)) {
echo 'Found Spaces';
}
Instead of Input::get('q'); use $q = $_GET['q'];
So your code becomes:
$q = $_GET['q'];
if(preg_match("/^\s+/", $q) || preg_match("/\s{2,}/", $q)) {
echo 'Found Spaces';
}
if(preg_match("/^\s+/", $q) || preg_match("/\s{2,}/", $q))
{
}
/\s+/g
\s to match space.
+ to said at least one.
g globally tag, all matches.
You can use a single call to preg_match with an alternation | to check for both scenario's.
As \s can also match a newline, you can use \h to match a horizontal whitespace char.
^\h|\h\h
Regex demo
$q = Input::get('q');
if(preg_match("/^\h|\h\h/", $q) ) {
echo 'Found Spaces';
}
Have you tried using PHP trim() function? Use trim() to remove redundant whitespaces, then apply more advanced filter or whatever you name it.
In case you want a boolean value, just check if the original string is different from trimmed string.
Document: https://www.php.net/manual/en/function.trim.php

Follow cloaked link with with chain of numbers to front

I'm building a small cloaking link script but I need to find each one with a different string number eg( 'mylinkname1'-1597). By the way: the number is always integer.
The problem is that I never know the string number so I was thinking to use regex but something is failing.
Here's what I got now:
$pattern = '/-([0-9]+)/';
$v = $_GET['v']
if ($v == 'mylinkname1'.'-'.$pattern) {$link = 'http://example1.com/';}
if ($v == 'mylinkname2'.'-'.$pattern) {$link = 'http://example2.com/';}
if ($v == 'mylinkname3'.'-'.$pattern) {$link = 'http://example3.com/';}
header("Location: $link") ;
exit();
The dash is already in the pattern so you don't have to add it in the if clause.
You can omit the capturing group around the digits -[0-9]+, and you have to use the pattern with preg_match.
You might update the format of the if statements to:
$pattern = '-[0-9]+';
if (preg_match("/mylinkname1$pattern/", $v)) {$link = 'http://example1.com/';}
To prevent mylinkname1-1597 being part of a larger word, you might surround the pattern with anchors ^ and $ to assert the start and end of the string or word boundaries \b
no need for regular expressions here at all just split the string on the hyphen and only match that, also I recommend a case\switch when you 3 or if\eleses:
$v=explode('-',$_GET['v']);
switch ($v[0]) {
case "mylinkname1":
$link = 'http://example1.com/';
break;
case "mylinkname2":
$link = 'http://example2.com/';
break;
case "mylinkname3":
$link = 'http://example3.com/';
break;
default:
echo "something not right";
}
header("Location: $link") ;
exit();

What will be regex for checking alphanumeric dot dash and underschore using preg_match?

I am checking username entered by user
I'm trying to validate usernames in PHP using preg_match() but I can't seem to get it working the way I want it. I require preg_match() to:
accept only letters , numbers and . - _
i.e. alphanumeric dot dash and underscore only, i tried regex from htaccess which is like this
([A-Za-z0-9.-_]+)
like this way but it doesnt seem to work, it giving false for simple alpha username.
$text = 'username';
if (preg_match('/^[A-Za-z0-9.-_]$/' , $text)) {
echo 'true';
} else {
echo 'false';
}
How can i make it work ?
i am going to use it in function like this
//check if username is valid
function isValidUsername($str) {
return preg_match('/[^A-Za-z0-9.-_]/', $str);
}
i tried answwer in preg_match() and username but still something is wrong in the regex.
update
I am using code given by xdazz inside function like this.
//check if username is valid
function isValidUsername($str) {
if (preg_match('/^[A-Za-z0-9._-]+$/' , $str)) {
return true;
} else {
return false;
}
}
and checking it like
$text = 'username._-546_546AAA';
if (isValidUsername($text) === true) {
echo 'good';
}
else{
echo 'bad';
}
You missed the +(+ for one or more, * for zero or more), or your regex only matches a string with one char.
if (preg_match('/^[A-Za-z0-9._-]+$/' , $text)) {
echo 'true';
} else {
echo 'false';
}
hyphen - has special meaning inside [...] that is used for range.
It should be in the beginning or in the last or escape it like ([A-Za-z0-9._-]+) otherwise it will match all the character that is in between . and _ in ASCII character set.
Read similar post Including a hyphen in a regex character bracket?
Better use \w that matches [A-Za-z0-9_]. In shorter form use [\w.-]+
What is the meaning for your last regex pattern?
Here [^..] is used for negation character set. If you uses it outside the ^[...] then it represents the start of the line/string.
[^A-Za-z0-9.-_] any character except:
'A' to 'Z',
'a' to 'z',
'0' to '9',
'.' to '_'
Just put - at the last in character class and add + after the char class to match one or more characters.
$text = 'username';
if (preg_match('/^[A-Za-z0-9._-]+$/' , $text)) {
echo 'true';
} else {
echo 'false';
}
function should be like this
function isValidUsername($str) {
return preg_match("/^[A-Za-z0-9._-]+$/", $str);
}

Regular Expression not allow duble underscores

I am writing my website user registration part, I have a simple regular expression as follows:
if(preg_match("/^[a-z0-9_]{3,15}$/", $username)){
// OK...
}else{
echo "error";
exit();
}
I don't want to let users to have usernames like: '___' or 'x________y', this is my function which I just wrote to replace duble underscores:
function replace_repeated_underScores($string){
$final_str = '';
$str_len = strlen($string);
$prev_char = '';
for($i = 0; $i < $str_len; $i++){
if($i > 1){
$prev_char = $string[$i - 1];
}
$this_char = $string[$i];
if($prev_char == '_' && $this_char == '_'){
}else{
$final_str .= $this_char;
}
}
return $final_str;
}
And it works just fine, but I wonder if I could also check this with regular expression and not another function.
I would appreciate any help.
Just add negative look-ahead to check whether there is double underscore in the name or not.
/^(?!.*__)[a-z0-9_]{3,15}$/
(?!pattern), called zero-width negative look-ahead, will check that it is not possible to find the pattern, ahead in the string from the "current position" (current position is the position that the regex engine is at). It is zero-width, since it doesn't consume text in the process, as opposed to the part outside. It is negative, since the match would only continue if there is no way to match the pattern (all possibilities are exhausted).
The pattern is .*__, so it simply means that the match will only continue if it cannot find a match for .*__, i.e no double underscore __ ahead in the string. Since the group does not consume text, you will still be at the start of the string when it starts to match the later part of the pattern [a-z0-9_]{3,15}$.
You already allow uppercase username with strtolower, nevertheless, it is still possible to do validation with regex directly by adding case-insensitive flag i:
/^(?!.*__)[a-z0-9_]{3,15}$/i

PHP regular expression allowing at most 1 '.' or '_' character in string, and '.' or '_' can't be at beginning or end of string

I am writing a PHP validation for a user registration form. I have a function set up to validate a username which uses perl-compatible regular expressions. How can I edit it so that one of the requirements of the regular expression are AT MOST a single . or _ character, but NOT allow that character at the beginning or end of the string? So for example, things like "abc.d", "nicholas_smith", and "20z.e" would be valid, but things like "abcd.", "a_b.C", and "_nicholassmith" would all be invalid.
This is what I currently have but it does not add in the requirements about . and _ characters.
function isUsernameValid()
{
if(preg_match("/^[A-Za-z0-9_\.]*(?=.{5,20}).*$/", $this->username))
{
return true; //Username is valid format
}
return false;
}
Thank you for any help you may bring.
if (preg_match("/^[a-zA-Z0-9]+[._]?[a-zA-Z0-9]+$/", $this->username)) {
// there is at most one . or _, and it's not at the beginning or end
}
You can combine this with the string length check:
function isUsernameValid() {
$length = strlen($this->username);
if (5 <= $length && $length <= 20
&& preg_match("/^[a-zA-Z0-9]+[._]?[a-zA-Z0-9]+$/", $this->username)) {
return true;
}
return false;
}
You could probably do the whole lot using just one regex, but it would be much harder to read.
You can use the following pattern, I have divided it into multiple lines to make it more understandable:
$pattern = "";
$pattern.= "%"; // Start pattern
$pattern.= "[a-z0-9]+"; // Some alphanumeric chars, at least one.
$pattern.= "[\\._]"; // Contains exactly either one "_" or one "."
$pattern.= "[a-z0-9]+"; // Some alphanumeric chars, at least one.
$pattern.= "%i"; // End pattern, optionally case-insensetive
And then you can use this pattern in your function/method:
function isUsernameValid() {
// $pattern is defined here
return preg_match($pattern, $this->username) > 0;
}
Here is a commented, tested regex which enforces the additional (unspecified but implied) length requirement of from 5 to 20 chars max:
function isUsernameValid($username) {
if (preg_match('/ # Validate User Registration.
^ # Anchor to start of string.
(?=[a-z0-9]+(?:[._][a-z0-9]+)?\z) # One inner dot or underscore max.
[a-z0-9._]{5,20} # Match from 5 to 20 valid chars.
\z # Anchor to end of string.
/ix', $username)) {
return true;
}
return false;
}
Note: No need to escape the dot inside the character class.

Categories