How can I check a string for multiple certain characters? - php

I have a string and I need to check it for several characters. I can do that with strpos();. But in this case, I would need to use strpose(); several times. something like this:
$str = 'this is a test';
if(
strpos($str, "-") === false &&
strpos($str, "_") === false &&
strpos($str, "#") === false &&
strpos($str, "/") === false &&
strpos($str, "'") === false &&
strpos($str, "]") === false &&
strpos($str, "[") === false &&
strpos($str, "#") === false &&
strpos($str, "&") === false &&
strpos($str, "*") === false &&
strpos($str, "^") === false &&
strpos($str, "!") === false &&
strpos($str, "?") === false &&
strpos($str, "{") === false &&
strpos($str, "}") === false
)
{ do stuff }
Now I want to know, is it possible to use a regex to define my condition summary?
Edit: here is some examples:
$str = 'foo' ----I want this output---> true
$str = 'foo!' -------------------------> false
$str = '}foo' -------------------------> false
$str = 'foo*bar' -------------------------> false
and so on. In other word, I want just text character: abcdefghi... .

You could use a basic regex:
$unwantedChars = ['a', '{', '}'];
$testString = '{a}sdf';
if(preg_match('/[' . preg_quote(implode(',', $unwantedChars)) . ']+/', $testString)) {
print "Contains invalid characters!";
} else {
print "OK";
}

Use negative lookahead assertion.
if (preg_match("~^(?!.*?[-_^?}{\]\[/'#*&#])~", $str) ){
// do stuff
}
This will do the stuff inside braces only if the string won't contain anyone of the mentioned characters.
If you want the string to contain only word chars and spaces.
if (preg_match("~^[\w\h]+$~", $str)){
// do stuff
}
or
AS #Reizer metioned,
if(preg_match("~^[^_#/'\]\[#&*^!?}{-]*$~", $str)){
Replace the * (present next to the character class) in the above with +, if you don't want to match an empty string.
For only alphabets and spaces.
if(preg_match("~^[a-z\h]+$~i", $str) ){

May be something like that:
function strpos_multi(array $chars, $str) {
foreach($chars as $char) {
if (strpos($str, $char) !== false) {
return false;
}
}
return true;
}
$res = strpos_multi(["-", "_", "#", "/", "'", "]", "[", "#", "&", "*", "^", "!", "?", "{", "}"], $str);
if ($res) {
//do some stuff
}

Related

how to search the entire string and format correctly

I'm trying to do this code.
Supposed I have a string with value 1.323,30 or 1,323,30 or 1.323.30
I want to change that to the correct format that was 1323.30 always.
I made this code but that's an alternative way to resolve that, but I want to resolve it without sending to the user a message.
if((isset($p["valor"])) && preg_match("/^[0-9,]+$/", $p["valor"])) {
$valor = str_replace(",", ".", $p['valor']);
}else{
$bnc->rollBack();
echo json_encode(array('ret' => '0', 'msg' => $erros['invalidvalue']));
return;
}
You can do this with a simple preg_replace. The replace function can take inputs in the form of array for all three of the parameters (pattern, replacement, & input) and returns an array.
Code
$numbers = [
"1.323,30",
"1,323,30",
"1.323.30",
];
$numbers = preg_replace(
["/[,.](\d{3})/", "/[,.](\d\d)$/"],
["$1", ".$1"],
$numbers
);
print_r($numbers);
Output:
Array
(
[0] => 1323.30
[1] => 1323.30
[2] => 1323.30
)
Regex 1
[,.](\d{3}) : Matches a comma OR a period.
Followed by three digits in a capture group
Regex 2
[,.](\d\d)$ : Matches a comma or a period.
Followed by two digits in a capture group.
Finishing with the end of the string.
I'll post this approach because I had already done this function before, but Steven's answer is a lot cleaner.
function alwaysValidNumber($string){
$dot_pos = strpos($string, '.');
$comma_pos = strpos($string, ',');
if ($dot_pos !== false && $comma_pos !== false && $dot_pos < $comma_pos) {
$string = str_replace(',', '.', str_replace('.', '', $string));
}else if ($comma_pos !== false && $dot_pos === false) {
$pos = strrpos($string, ',');
if($pos !== false)
{
$string = substr_replace($string, '.', $pos, 1);
}
}else if ($dot_pos !== false && $comma_pos === false) {
while (substr_count($string, '.') > 1) {
$pos = strpos($string, '.');
if ($pos !== false) {
$string = substr_replace($string, '', $pos, 1);
}
}
}
$string = str_replace(',', '', $string);
return $string;
}
Example:
$values = [
'10.0000,0',
'1,323.30',
'1,323,30',
'1.323.30',
'1.32',
'1,32',
];
foreach ($values as $key => $value) {
$number = alwaysValidNumber($value);
echo $number . '<br>';
}
Output:
100000.0
1323.30
1323.30
1323.30
1.32
1.32

Strpos with both integer and word

I'm stuck. Ignore the top line, no use for date yet, but will be using in a bit. Having issues primarily with this line:
if(strpos($line, $extension) !== false and (preg_match('#\d#',$line !== false))){
I'm trying to do is that if a domain name ($line) is a .com and has no numbers then echo it. All of the preg_replace and strlen seems to be working, but I can't get it to only perform the way I need. I need to put the preg_match outside of the <=40 rule as it may be causing confusion?
<?php
date_default_timezone_set('UTC');
$extension = '.com';
$lines = file('PoolDeletingDomainsList.txt');
echo "<b>4 Letter premiums for ". date("n/j/Y") .":</b><br />";
foreach($lines as $line)
if(strlen($line)<=40) {
{
// Check if the line contains the string we're looking for, and print if it does
if(strpos($line, $extension) !== false and (preg_match('#\d#',$line !== false))){
$line = preg_replace('/12:00:00 AM,AUC\b/','<br />', $line);
$line = preg_replace('/,9\/28\/2013/', '', $line);
echo $line;
}
}
}
?>
Return Values
preg_match() returns 1 if the pattern matches given subject, 0 if it does not, or FALSE if an error occurred.
Manual preg_match
if(strpos($line, $extension) !== false and (preg_match('#\d#',$line) !== false))){
$line = preg_replace('/12:00:00 AM,AUC\b/','<br />', $line);
$line = preg_replace('/,9\/28\/2013/', '', $line);
echo $line;
}
replace with
if ((false !== strpos($line, $extension)) && (1 === preg_match('#\d#',$line))){
$line = preg_replace('/12:00:00 AM,AUC\b/','<br />', $line);
$line = preg_replace('/,9\/28\/2013/', '', $line);
echo $line;
}
This will check if $line contains .com and has numbers (otherwise those preg_replace would have nothing to work with).
Here is what seemed to work for me.
date_default_timezone_set('UTC');
$extension = '.com';
$lines = file('PoolDeletingDomainsList.txt');
echo "<b>4 Letter premiums for ". date("n/j/Y") .":</b><br />";
foreach($lines as $line)
if(strlen($line)<=36) {
{
// Check if the line contains the string we're looking for, and print if it does
$line = preg_replace('/12:00:00 AM,AUC\b/','<br />', $line);
$line = preg_replace('/,9\/28\/2013/', '', $line);
if ((false !== strpos($line, $extension)) && (0 === preg_match('#\d#',$line)) && (0 === preg_match('/-/', $line))){
echo $line;
}
}
}
?>
According to the preg_match documentation:
preg_match() returns 1 if the pattern matches given subject, 0`` if it does not, or FALSE if an error occurred.
So, according to your current condition, the if statement will evaluate to TRUE if preg_match returns any value that's not FALSE (which includes 1 and 0). And preg_match returns 1 if a match is found, so all your domains will pass the condition and echoed.
To fix the error, change your if statement to:
if(strpos($line, $extension) !== false && !preg_match('#\d#',$line)) {
So you're searching for .com domains that have no numbers in it ("premium domains").
<?php
$lines = array(
'example.com',
'exa13mple.com',
'domain.org',
'google.com',
'37signals.com'
);
foreach ($lines as $line)
{
$matches = array();
$isComDomain = preg_match('/\w+\\.com/', $line, $matches);
$hasNoNumbers = !empty($matches) ? preg_match('/^[a-zA-Z]+\\.com$/', $matches[0]) : false;
if ($isComDomain && $hasNoNumbers) {
print $matches[0] . "\n";
}
}
The isComDomain is a boolean telling if it found a [word characters].com from the line. And if it found, it stores the found domain name in $matches[0].
Then the hasNoNumbers is a boolean telling if the .com domain name contained only chars from a-z and A-Z. You may wish to include "-" in the regex if you allow dashes.

How to remove specific html tags from a line in string?

$find = '{<p>something</p>}';
$str1 = "<p>{<p>something</p>}</p>\r\ntext<p>something else</p>";
// or
$str2 = "<p>something</p>\r\n{<p>something</p>}aa<p>t</p>\r\ntext<p>something else</p>";
Basically, $find can be anywhere in the string. New lines delimiter is "\r\n".
I need to find $find in the $str and remove specific html tags around $find in that specific string line. No tags should be removed from $find.
Expected output would be
// For $str1
$str1 = "{<p>something</p>}\r\ntext<p>something else</p>";
// For $str2
$str2 = "<p>something</p>\r\n{<p>something</p>}aat\r\ntext<p>something else</p>";
The string might be very long, so no regex solutions please.
What I have figured out:
$pos = strpos($str, $find);
if ($pos !== false) {
$contentLength = strlen($str);
$lineStart = (int)strrpos($str, "\r\n", -$contentLength+$pos); // cast false to 0 (start of string)
$lineEnd = strpos($str, "\r\n", $pos);
if ($lineEnd === false)
$lineEnd = strlen($str);
$lineLength = $lineEnd-$lineStart;
if ($lineLength < 0)
return;
var_dump(substr($str, $lineStart, $lineLength));
}
Which dumps that specific line in the string.
My final solution:
function replace($find, $str, $replace) {
$pos = strpos($str, $find);
if ($pos !== false) {
$delim = "\r\n";
$contentLength = strlen($str);
$lineStart = strrpos($str, $delim, -$contentLength+$pos);
if ($lineStart === false)
$lineStart = 0;
else
$lineStart += strlen($delim);
$lineEnd = strpos($str, $delim, $pos);
if ($lineEnd === false)
$lineEnd = strlen($str);
$lineLength = $lineEnd - $lineStart;
$line = substr($str, $lineStart, $lineLength);
$posLine = strpos($line, $find); // Where $find starts
$findLength = strlen($find);
$line = substr_replace($line, '', $posLine, $findLength); // Remove $find from $line
$begin = replaceTags(substr($line, 0, $posLine));
$end = replaceTags(substr($line, $posLine));
return substr_replace($str, $begin.$replace.$end, $lineStart, $lineLength);
}
}
function replaceTags($str) {
return str_replace(array('<p>', '</p>'), '', $str);
}
echo replace($find, $str, $replace);

Checking if sentence contains a word in PHP

How can I check if a sentence contains a word. I used names sentence and word instead of string and substring expressly. For example:
for sentence
$s = "Ala makota, a kot ma przesrane";
calling function
checkIfContains("kota",$s)
returns false.
But for
checkIfContains("makota",$s)
returns true.
If you're looking to match only full words, you'll need a regular expression to accomplish this. Try the following:
<?php
function checkIfContains( $needle, $haystack ) {
return preg_match( '#\b' . preg_quote( $needle, '#' ) . '\b#i', $haystack ) !== 0;
}
You need strpos.
if (strpos($s, 'kota') !== false) {
}
Or if you insist..
function checkIfContains($needle, $haystack) {
return (strpos($haystack, $needle) !== false);
}
For full words you could consider regex:
if (preg_match('/\bkota\b/i', $s)) { }
I'd use explode to separate the string into an array based on a character (" " in this case).
function checkIfContains($toTest, $toCheck)
{
// Check if length of either string is zero for validation purposes
if(strlen($toTest) == 0 || strlen($toCheck) == 0)
{
return false;
}
$exploded = explode(" ", $toCheck);
foreach($exploded as $word)
{
if($word == $toTest)
{
// Found a match, return true!
return true;
}
}
// None matched, return false
return false;
}
You can try :
function checkIfContains($needle, $haystack) {
// Remove punctuation marks
$haystack = preg_replace('/[^a-zA-Z 0-9]+/', '', $haystack);
// Explode sentence with space
$haystack = explode(' ', $haystack);
// Check if $needle exist
return in_array($needle, $haystack);
}
$string = "Ala makota, a kot ma przesrane";
checkIfInString("makota", $string);
function checkIfInString($needle, $haystack) {
$delimiters = ' ,.';
return in_array($needle, explode($haystack, $delimiters);
}
you can try like :
if(strpos($s,"kota") !== false){
echo true;
}
or :
function checkIfContains($string, $letter){
return strpos($string, $letter) !== false;
}

Needle is in haystack but barn door is jammed shut!

The test below returns false ($pos = 0) when $haystack = "my keyword" and $needle = "my keyword", presumably because my stripos test returns 0 since there is no empty space in the barn.
What do I need to change in the comparison to return true in this case?
function my_test($post){
if($post->post_title == "") return false;
$haystack = my_esc2($post->post_title);
$needle = trim(my_getKeyword($post));
$pos = stripos($haystack, $needle);
if ($pos !== false) return true;
//returns 0 when $needle and $haystack are the same exact phrase. but should return 1
}
function my_getKeyword($post)
{
$myKeyword = get_post_meta($post->ID, '_my_keyword', true);
if($myKeyword == "") $myKeyword = $post->post_title;
$myKeyword = my_esc($myKeyword);
return " ".$myKeyword;
}
function my_esc($str, $quotation='"') {
if ($quotation != '"' && $quotation != "'") return false;
return str_replace($quotation, $quotation.$quotation, $str);
}
function my_esc2($str, $quotation='"') {
if ($quotation != '"' && $quotation != "'") return false;
return str_replace($quotation, '', $str);
}
If both strings are the same, stripos is supposed to return 0 as 0 is the position in the string where the match if found.
However, you are using the !== operator, so that test should return true anyway (by the way, you can just use return ($pos !== false)).
Are you sure you are getting to that statement, can you echo both $haystack and $needle right before the return statement?
It seems to me that haystack and needle are not the same or needle is not found or ($post->post_title == "")...

Categories