PHP - Replacing characters with stars, except when there is a minus - php

How can I replace a string with stars except the first and the last letter but not a minus in case there is one.
Here for better illustration what I try to get:
From:
url-name
To
u**-***e
This is what I have so far:
function get_starred($str) {
$len = strlen($str);
return substr($str, 0, 1).str_repeat('_', $len - 2).substr($str, $len - 1, 1);
}

You could use the PCRE verbs to skip the first character of a string, last character of a string, and any -s. Like this:
(^.|-|.$)(*SKIP)(*FAIL)|.
https://regex101.com/r/YfrZ8r/1/
PHP example using preg_replace
preg_replace('/(^.|-|.$)(*SKIP)(*FAIL)|./', '*', 'url-name');
https://3v4l.org/0dSPQ

hey try implmenting the following:
function get_starred($str) {
$str_array =str_split($str);
foreach($str_array as $key => $char) {
if($key == 0 || $key == count($str_array)-1) continue;
if($char != '-') $str[$key] = '*';
}
return $str;
}

user3783242 has a great solution - However, if you for some reason do not want to use preg_replace(), you could do the following:
function get_starred($str) {
//make the string an array of letters
$str = str_split($str);
//grab the first letter (This also removes the first letter from the array)
$first = array_shift($str);
//grab the last letter (This also removes the last letter from the array)
$last = array_pop($str);
//loop through leftover letters, replace anything not a dash
//note the `&` sign, this is called a Reference, it means that if the variable is changed in the loop, it will be changed in the original array as well.
foreach($str as &$letter) {
//if letter is not a dash, set it to an astrisk.
if($letter != "-") $letter = "*";
}
//return first letter, followed by an implode of characters, followed by the last letter.
return $first . implode('', $str) . $last;
}

Here is mine:
$string = 'url-name foobar';
function star_replace($string){
return preg_replace_callback('/[-\w]+/i', function($match){
$arr = str_split($match[0]);
$len = count($arr)-1;
for($i=1;$i<$len;$i++) $arr[$i] = $arr[$i] == '-' ? '-' : '*';
return implode($arr);
}, $string);
}
echo star_replace($string);
This works on multiple words.
Output
u**-***e f****r
Sandbox
And it also takes into account puctuation
$string = 'url-name foobar.';
Output
u**-***e f****r.

Related

Match exact word is available or not in string in php

I have below string i want to exact word is available or not in php
Example
$String = 'http://www.testurl.com/article/test.php';
$word = '/article/';
Now i want to check '/article/' is available or not in string, if the word is not contain start start and end slash then it should be return false.
Given that you're really just searching on a literal string match, you may use strpos here:
$input = 'http://www.testurl.com/article/test.php';
$word = '/article/';
if (strpos($input, $word) !== false) {
echo "Word Found!";
}
else {
echo "Word Not Found!";
}
You may also use preg_match here:
$input = 'http://www.testurl.com/article/test.php';
if (preg_match("$/article/$", $input)) {
echo "YES"; // prints YES
}
Note here that we are using $ as the delimiter character in the pattern being passed to preg_match. More typically, we see / being used, but you are trying to actually match literal forward slashes, we use something else.
Notwithstanding the fine answer from Tim, you may also be interested in a (admittedly less elegant) solution with logic to find a word match in a string.
We use the fact that the string datatype allows array-like([]) access to characters in a string. I.e. we can iterate through the string to find a word match using this technique.
<?php
$match = findWord($word, $string);
function findWord(string $word, string $string)
{
$len = strlen($string);
$lenWord = strlen($word);
for ($i = 0; $i < $len; $i++) {
$match = '';
if ($string[$i] === $word[0]) {
$match .= $word[0];// found a match for first char of $word
for ($j = 1; $j < $lenWord; $j++) { // see if we can match whole word char by char
if (isset($string[$i+$j]) && $word[$j] === $string[$i + $j]) {
$match .= $string[$i + $j];
} else break;
}
if ($match === $word) return $match; // we have a full match
}
}
return false; // no match found
}
You can play with the function in this demo

Determine the position of a special character in the string in PHP

I have to determine the position of a special character in the string for example:
E77eF/74/VA on 6 and 9 position (counting from 1)
we have '/' so I have to change them to position number -> E77eF6749VA
On MSSQL I could use PATINDEX but I need to use php for this.
It should work for everything except 0-9a-zA-Z
I found strpos() and strrpos() on php.net but I doens't work well for me.
Anyway tries to do something like that?
<?php
$content = 'E77eF/74/VA';
//With this pattern you found everything except 0-9a-zA-Z
$pattern = "/[_a-z0-9-]/i";
$new_content = '';
for($i = 0; $i < strlen($content); $i++) {
//if you found the 'special character' then replace with the position
if(!preg_match($pattern, $content[$i])) {
$new_content .= $i + 1;
} else {
//if there is no 'special character' then use the character
$new_content .= $content[$i];
}
}
print_r($new_content);
?>
Output:
E77eF6749VA
Might not be the most efficient way, but works.
$string = 'E77eF/74/VA';
$array = str_split($string);
foreach($array as $key => $letter){
if($letter == '/'){
$new_string.= $key+1;
}
else{
$new_string.= $letter;
}
}
echo $new_string; // prints E77eF6749VA

string to float and vice versa

how can i convert it into float and then increment it and then convert back to string.
if($set==$Data_Id)
{
$rel='1.1.1.2';
}
after increment it should be like 1.1.1.3.
Please any help.
so crazy, it may work
$rel='1.1.1.2';
echo substr($rel, 0, -1). (substr($rel,-1)+1); //1.1.1.3
the big question is what do you want to happen if the string ends in 9 ??
Here's a slightly different approach.
<?php
function increment_revision($version) {
return preg_replace_callback('~[0-9]+$~', function($match) {
return ++$match[0];
}, $version);
}
echo increment_revision('1.2.3.4'); //1.2.3.5
Anthony.
"1.1.1.2" is not a valid number. So you'll have to do something like this:
$rel = '1.1.1.2';
$relPlusOne = increment($rel);
function increment($number) {
$parts = explode('.', $number);
$parts[count($parts) - 1]++;
return implode('.', $parts);
}
If this is exactly the case you need to solve, you could do it with intval(), strval(), str_replace(), substr() and strlen().
$rel = '1.1.1.2'; // '1.1.1.2'
// replace dots with empty strings
$rel = str_replace('.', '', $rel); // '1112'
// get the integer value
$num = intval($rel); // 1112
// add 1
$num += 1; // 1113
// convert it back to a string
$str = strval($num); // '1113'
// initialize the return value
$ret = '';
// for each letter in $str
for ($i=0; $i<strlen($str); $i++) {
echo "Current ret: $ret<br>";
$ret .= $str[$i] . '.'; // append the current letter, then append a dot
}
$ret = substr($ret, 0, -1); // remove the last dot
echo "Incremented value: " . $ret;
This method will change 1.1.1.9 to 1.1.2.0, however. If that's what you want, then this will be fine.

Autodetect punctuation in a HTML string, and split the string there

I have a set of punctuation characters:
$punctuation = array('.', '!', ';', '?');
A character limit variable:
$max_char = 55;
And a string with HTML:
$string = 'This is a test string. With HTML.';
How can I split this string to maximum $max_chr characters, using one of the characters in the $punctuation array as "keys" ?
So basically the string should split at the nearest punctuation character, but not inside a HTML tag definition/attribute (It doesn't matter if the split occurs inside a tag's contents and the tag remains unclosed -- because I'm checking for unclosed tags later).
If you want to know whether or not you're inside a tag you might need to do some kind of state machine, and then make use of a loop on the string. You can reference a string sortof like an array, so you can do something like:
$punctuation = array('.', '!', ';', '?');
$in_tag = false;
$max_char = 55;
$string = 'This is a test string. With HTML.';
$str_length = strlen($string) > $max_char ? $max_char : strlen($string);
for($i = 0; $i < $str_length; $i++)
{
$tempChar = $string[$i]; //Get the character at position $i
if((!$in_tag) && (in_array($tempChar, $punctuation)))
{
$string1 = substr($string, 0, $i);
$string2 = substr($string, $i);
}
elseif((!$in_tag) && ($tempChar == "<"))
{
$in_tag = true;
}
elseif(($in_tag) && ($tempChar == ">"))
{
$in_tag = false;
}
}

How to get position of last letter in a string in php?

Example of a string: "Some text.....!!!!!!!!?????"
Using PHP how would I get the position of the last letter (or even alphanum character) which in this example is the letter t?
You could use preg_match_all with the regular expression \p{L} to find all Unicode letters. With the additional flag PREG_OFFSET_CAPTURE you get also the offsets:
$str = "Some text.....!!!!!!!!?????";
if (preg_match_all('/\p{L}/u', $str, $matches, PREG_OFFSET_CAPTURE) > 0) {
$lastMatch = $matches[0][count($matches[0])-1];
echo 'last letter: '.$lastMatch[0].' at '.$lastMatch[1];
} else {
echo 'no letters found';
}
$s = "Some text.....!!!!!!!!embedded?????";
$words = str_word_count($s,2);
$lastLetterPos = array_pop(array_keys($words)) + strlen(array_pop($words)) - 1;
echo $lastLetterPos;
If you want to allow for alphanum rather than just alpha:
$s = "Some text.....!!!!!!!!embedded21?????";
$words = str_word_count($s,2,'0123456789');
$lastLetterPos = array_pop(array_keys($words)) + strlen(array_pop($words)) - 1;
echo $lastLetterPos;
To add other characters as valid:
$s = "Some text.....!!!!!!!!embedded!!à?????";
$words = str_word_count($s,2,'0123456789ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝßàáâãäåæçèéêëìíîïðñòóôõöùúûüýÿ');
$lastLetterPos = array_pop(array_keys($words)) + strlen(array_pop($words)) - 1;
echo $lastLetterPos;
try substr() ;)
echo substr('abcdef', -1, 1);
It all depends on what you consider a letter, and what you want to do with "Some!!!???text???!!!" for example:
The naive solution would be to iterate from the last position in the string to find the first character you want to keep, then return that. (Or iterate from the beginning to find the first character you want to stop at, then return the one before it.)
Or you can use a regex to match what you want to keep, then take the last match. (Or use a regex replace to remove what you don't want to keep, then take the last character.)
Naive:
<?php
$s = "Some text.....!!!!!!!!?????";
$ary = str_split($s);
$position = 0;
$last = 0;
foreach ($ary as $char) {
if (preg_match("/[a-zA-Z0-9]/", $char)) {
$last = $position;
}
$position += 1;
}
echo $last;
?>
<?php
$str = '"Some text.....!!!!!!!!?????"';
$last = -1;
foreach(range('a', 'z') as $letter)
{
$last = max($last, strripos($str, $letter));
}
echo "$last\n"; // 9
?>
Here is a simple and straight-forward O(n) algorithm.
From the manual for ctype_alpha():
In the standard C locale letters are
just [A-Za-z]
If you need a different locale, you should abstract the function that determines if a character is alpha or not. That way you can keep this algorithm and adapt to varying languages.
function lastAlphaPosition($string) {
$lastIndex = strlen($string)-1;
for ($i = $lastIndex; $i > 0; --$i) {
if (ctype_alpha($string[$i])) {
return $i;
}
}
return -1;
}
$testString = 'Some text.....!!!!!!!!?????';
$lastAlphaPos = lastAlphaPosition($testString);
if ($lastAlphaPos !== -1) {
echo $testString[$lastAlphaPos];
} else {
echo 'No alpha characters found.';
}

Categories