allocating a string based on PHP if statement - if-statement

I quite new to PHP this seems to be causing me problems:
<?php
$ppe1="Water";
echo $ppe1;
if ($ppe1="Tap") {
$dog="time";
}
else
{$dog="travel";}
echo $dog;
?>
I am obviously being bery stupid but I cannot seem to allocate the $dog string based on the if statement

You should have a read on:
Comparison Operators.
In short: You are not comparing but assigning a value with =.
<?PHP
$ppe1 = "Walter";
$dog = $ppe1 === "Tap" ? "time" : "travel";
echo $dog;
This makes use of the ternary operator which is basically $variable = boolean expression ? then : else;
Or with your code structure:
<?PHP
$ppe1 = "Walter";
$dog = "";
if($ppe1 === "Tap")
{
$dog = "time";
}
else
{
$dog = "travel";
}
echo $dog;

Take a look at the Comparison Operators. Use the following code. Also as you said you are a beginner, I recommend you to read this.
<?php
$ppe1 = "Water";
echo $ppe1; // "Water"
if ($ppe1 == "Tap") {
$dog = "time";
} else {
$dog="travel";
}
echo $dog; // "travel"
?>

Related

Conditional If with REGEX

I'm working on a function to try some regex. Let me explain.
function traitement
{
if ($Matches.NAME -match "^A_(?<test1>[\w{1,6}]{1,7})")
{
[void]($memberOfCollection.add($Matches.test1))
}
elseif ($Matches.NAME -match "^A_(?<test2>[]*)")
{
[void]($memberOfCollection.add($Matches.test2))
}
else
{
[void]($memberOfCollection.add($Matches.NAME))
}
}
I have $Matches.NAME return string like "A_UserINTEL", "A_UserINTELASUS" or "A_UserINTEL_Adobe"
I need to differentiate 2 strings coming from $Matches.NAME and therefore write several tests.
"A_UserINTEL" and "A_UserINTELASUS" must return "UserINTEL".
"A_UserINTEL_Adobe" must return "UserINTEL_Adobe"
Test1 allows me to retrieve "UserINTEL" but I didn't succeed test2 to bring me "UserINTEL_Adobe".
Any idea? Thank you.
There's a;ways more ways then just one, especially when it comes to regular expressions, but here's one way:
function traitement {
# just for more clarity in the rest of the code
$name = $Matches.NAME
if ($name -match '^A_UserIntel(?:ASUS)?$') {
# the regex tests for "A_UserINTEL" or "A_UserINTELASUS"
[void]($memberOfCollection.add("UserINTEL"))
}
elseif ($name -match '^A_UserIntel_Adobe$') {
# this elseif is basically the same as
# elseif ($name -eq 'A_UserIntel_Adobe') {
# no real need for regex there..
[void]($memberOfCollection.add("UserINTEL_Adobe"))
}
else {
[void]($memberOfCollection.add($name))
}
}

regex validating telephone number, but chops white space using perl

So I have an HTML field in a form that takes in a phone number. It validates it correctly when I use () or / or - however, if I put in say 555 123 4567, it returns 555. As always your help is greatly appreciates it.
Here is my code
my $userName=param("userName");
my $password=param("password");
my $phoneNumber=param("phoneNumber");
my $email=param("email");
my $onLoad=param("onLoad");
my $userNameReg = "[a-zA-Z0-9_]+";
my $passwordReg = "([a-zA-Z]*)([A-Z]+)([0-9]+)";
my $phoneNumberReg = "((\(?)([2-9]{1}[0-9]{2})(\/|-|\)|\s)?([2-9]{1}[0-9]{2})(\/|-|\s)?([0-9]{4}))";
my $emailReg = "([a-zA-Z0-9_]{2,})(#)([a-zA-Z0-9_]{2,})(.)(com|COM)";
if ($onLoad !=1)
{
#controlValue = ($userName, $password, $phoneNumber, $email);
#regex = ($userNameReg, $passwordReg, $phoneNumberReg, $emailReg);
#validated;
for ($i=0; $i<4; $i++)
{
$retVal= validatecontrols ($controlValue[$i], $regex[$i]);
if ($retVal)
{
$count++;
}
if (!$retVal)
{
$validated[$i]="*"
}
}
sub validatecontrols
{
my $ctrlVal = shift();
my $regexVal = shift();
if ($ctrlVal =~ /^$regexVal$/)
{
return 1;
}
return 0;
}
}
*html code is here*
I realize that this is part of an assignment, so you may be working under specific restraints. However, your attempt to abstract out your data validation is honestly just making things messy and harder to follow. It also ties you down to specifically regex tests, which may not actually be the best bet. As has already been said, email validation should be done via a module.
Also, for this phone validation, an easier solution is just to strip out anything that isn't a number, and then do your validation test. The below code demonstrates what I'm talking about:
my $userName = param("userName");
my $password = param("password");
my $phoneNumber = param("phoneNumber");
my $email = param("email");
my $onLoad = param("onLoad");
my $error = 0;
if ($onLoad !=1)
{
if ($username !~ /^[a-zA-Z0-9_]+$/) {
$username = '*';
$error++;
}
if ($password !~ /^[a-zA-Z]*[A-Z]+[0-9]+$/) {
$password = '*';
$error++;
}
(my $phoneNumOnly = $phoneNumber) =~ s/\D//g;
if ($phoneNumOnly !~ /^1?[2-9]{1}\d{2}[2-9]{1}\d{6}$/) {
$phoneNumber = '*';
$error++;
}
if ($email !~ /^\w{2,}\#\w{2,}\.com$/i) {
$email = '*';
$error++;
}
}
*html code is here*
That regex you're using looks a overly complicated. You have a lot of capturing groups in there, but I get the feeling you're mostly using them to define "OR" statements with the vertical bar. It's usually a lot easier to just use brackets for this purpose if you're only selecting single characters. Also, it's not a good idea to use\s for normal spaces, since this will actually match any whitespace character (tabs and newlines). Maybe try something like this:
(?:\(?[2-9]\d{2}\)?[-\/ ]?)?[2-9]\d{2}[-\/ ]?\d{4}

Perl argument switch based on regex

I have a Perl script that takes in arguments. When I had single value arguments, the following code sufficed:
switch ($ARGV[0]) {
case "--cmd1" {
$action = "cmd1";
}
case "--cmd2" {
$action = "cmd2";
}
Now, I have a case where the command, cmd3 has a parameter, as in --cmd3=SOMETHING. Since SOMETHING can vary, the simple switch/case does not work anymore. Basically, I need to do a switch/case on the command itself. I thought I could use a regex with the first matching group being the command and the second being the optional equals. The following does not work, but it illustrates what I'm trying to do.
$ARGV[0] =~ m/(.*?)(=.*){0,1}/;
my $cmd = $1;
my $equals = $2;
switch ($cmd) {
case "--cmd1" {
$action = "cmd1";
}
case "--cmd2" {
$action = "cmd2";
}
case "--cmd3" {
$action = "cmd3";
print $equals;
}
:::::::::::::::::::::::::::::::::::EDIT:::::::::::::::::::::::::::::::::::::::::::::::::::::
I figured it out, but I'll give the guy who answered upvotes and accept anyway. I could not use if because that means restructuring everything. Here's the solution.
switch ($ARGV[0]) {
case "--cmd1" {
$action = "cmd1";
}
case "--cmd2" {
$action = "cmd2";
}
case m/--cmd3(=.*)?/ {
$ARGV[0] =~ m/--cmd3(=.*)?/;
$action = "cmd3";
print $1;
}
Why aren't you using Getopt::Long?
How about something like this?
my $cmd = "";
my $equals = "";
if($ARGV[0] =~ m/^\-\-cmd1$/){$cmd="cmd1"}
if($ARGV[0] =~ m/^\-\-cmd2$/){$cmd="cmd2"}
if($ARGV[0] =~ m/^\-\-cmd3=(.*)$/){$cmd="cmd3";$equals=$1}

match words in a string

I have the next code:
$string = "hello to all world";
$strings_compare = tomorrow, hello, world;
$string_arrays =split(',',$strings_compare);
for ($i=0; $i<count($string_arrays); $i++){
$resultado = preg_match("/$string_arrays[$i]/",$string);
if($resultado == false){
echo "no match";
}else {
echo "match";
}
}
in this code the results are:
no match, match, no match
and the results should be: no match, match and match. What is my error?
if I change the $string by $string='say hello to all world now'
the results are match, match, match, this is OK.
It works fine for me when I'm using valid array syntax.
<?php
$string = "hello to all world";
$string_arrays = array("tomorrow", "hello", "world");
for ($i=0; $i<count($string_arrays); $i++) {
$resultado = preg_match("/$string_arrays[$i]/",$string);
if(!$resultado) {
echo "no match";
} else {
echo "match";
}
}
Returns
no matchmatchmatch
Try this:
$resultado = preg_match("/".preg_quote($string_arrays[$i])."/",$string);
Also:
$string_arrays = array("tomorrow", "hello", "world");

How to make perl regex options conditional

DON'T ASK WHY but...
I have a regex that needs to be case insensitive if run on windows BUT case sensitive when run on *nix.
Here is an example snippet of what I am kind-of doing at the moment.
sub relative_path
{
my ($root, $path) = #_;
if ($os eq "windows")
{
# case insensitive with regex option 'i'
if ($path !~ /^\Q$root\E[\\\/](.*)$/i)
{
print "\tFAIL:$root not in $path\n";
}
else
{
return $1;
}
}
else
{
# case sensitive
if ($path !~ /^\Q$root\E[\\\/](.*)$/)
{
print "\tFAIL:$root not in $path\n";
}
else
{
return $1;
}
}
return "";
}
Argh! The repetition hurts my OCD but my perl-fu is weak. Somehow I want to make the regex option 'i' for case-insensitive conditional but I don't now how?
You can use an extended construct to specify the option. For example:
#!/usr/bin/env perl
use warnings; use strict;
my $s = 'S';
print check($s, 'i'), "\n";
print check($s, '-i'), "\n";
sub check {
my ($s, $opt) = #_;
return "Matched" if $s =~ /(?$opt)^s\z/;
return "Did not match";
}
See perldoc perlre.
You can create patterns and store them in scalars using the qr operator:
sub relative_path
{
my ($root, $path) = #_;
my $pattern = ($os eq "windows") ? qr/^\Q$root\E[\\\/](.*)$/i : qr/^\Q$root\E[\\\/](.*)$/;
if ($path !~ $pattern)
{
print "\tFAIL:$root not in $path\n";
}
else
{
return $1;
}
}
This might not be 100% perfect, but hopefully you should get the idea.
Make sure to check out the section "Quote and Quote-Like Operators" in perlop.
EDIT: Okay, here's a DRY solution since people are complaining about it.
sub relative_path
{
my ($root, $path) = #_;
my $base_pattern = qr/^\Q$root\E[\\\/](.*)$/;
my $pattern = ($os eq "windows") ? qr/$base_pattern/i : $base_pattern;
if ($path !~ $pattern)
{
print "\tFAIL:$root not in $path\n";
}
else
{
return $1;
}
}
In addition to achieving the stated objective, this properly handles volumes unlike the regex patterns previously posted.
use Path::Class qw( dir );
sub relative_path {
my ($root, $path) = #_;
if ($^O =~ /Win32/) {
require Win32;
$root = Win32::GetLongPathName($root);
$path = Win32::GetLongPathName($path);
}
$root = dir($root);
$path = dir($path);
if ($root->subsumes($path)) {
return $path->relative($root);
} else {
print "\tFAIL:$root not in $path\n";
return "";
}
}
By the way, it's not very appropriate to handle the error there. The function should return an error signal (return undef, throw an exception, etc) and the caller should handle it as it sees fit. Separations of concerns.
You can also do it using local modifiers (perl extended regexes option):
sub relative_path
{
my ($root, $path) = #_;
my $pattern = "^\Q$root\E[\\\/](.*)$";
$pattern = "(?i)$pattern" if ($os eq "windows");
if ($path =~ /$pattern/)
{
return $1;
}
else
{
print "\tFAIL:$root not in $path\n";
}
}
(after I typed my answer I saw that Sinan also suggested it, but I decided to post my answer as well, since it gives a concreter answer to the question)