How many times "-" at beginning of string (before alphabet letter) - php

I'm having trouble knowing how many times that the - character is in front of my string.
Some examples:
$string = "-Lorem Ipsum"; // 1
$string = "--Lorem Ipsum"; // 2
$string = "---Lorem Ipsum"; // 3
$string = "--Lorem-Ipsum"; // 2
But how can I find this? I know you can search the number of occurrences of a character in a string. But I want the number of - characters before an alphabet letter. Not all the sequences (see last example).
How should I approach this?

You can use the old school trick of using a string as an array here as such:
$search="-";
$i=0;
while($string[$i]==$search)
{
$i++;
}
echo "Found $i instances at the start of the string.";

What about using ltrim() and strlen()
echo strlen($string) - strlen(ltrim($string, "-"));
See example at eval.in

it would also work -
preg_match('/(?!-)/', $string, $match, PREG_OFFSET_CAPTURE);
$match - the position of any character but - which is indeed the count of -.

Related

preg replace everything BUT digits over 5 in length

I have a string:
3 pk. Ready-Dough White Loaves Included $3.99 - 47500 - 00892, 48101
I want to keep only groups of digits longer than 5 characters, and if possible, any dashes or commas between them.
e.g.
47500-00892,48101
My first step was to strip out groups of digits < 4:
preg_replace('/\d{1,4}/', '', $string);
My thinking was "replace any block of digits from 1 to 4 with nothing", but that doesn't do exactly what I thought. Maybe I'm just missing an operator?
Then I was going to strip out all letters and all punctuation except , and -. In my example I would've been left with a starting - because of it being in a string, but a trim() would've been fine to clean that up.
Any help is appreciated!
Had I been patient for 5 more minutes, I would've found the answer: \b
For some reason, working with digits didn't trigger that I needed to use 'word boundaries'.
$string = preg_replace('/\b\d{1,4}\b/', '', $string);
$string = preg_replace('/[^0-9-,]/', '', $string);
$string = trim($string, ',-');
Since there's no reason to perform a replacement, you can use preg_match_all to take what you want and reduce the result array:
$re = '/\d{5,}(?:(?=\s*([-,])\s*\d{5}))?/';
$str = '3 pk. Ready-Dough White Loaves Included $3.99 - 47500 - 00892, 48101';
if ( preg_match_all($re, $str, $matches, PREG_SET_ORDER) ) {
$result = array_reduce($matches, function ($c,$i) { return $c . implode('', $i); });
echo $result;
}

php regex replace each character with asterisk

I am trying to something like this.
Hiding users except for first 3 characters.
EX)
apple -> app**
google -> goo***
abc12345 ->abc*****
I am currently using php like this:
$string = "abcd1234";
$regex = '/(?<=^(.{3}))(.*)$/';
$replacement = '*';
$changed = preg_replace($regex,$replacement,$string);
echo $changed;
and the result be like:
abc*
But I want to make a replacement to every single character except for first 3 - like:
abc*****
How should I do?
Don't use regex, use substr_replace:
$var = "abcdef";
$charToKeep = 3;
echo strlen($var) > $charToKeep ? substr_replace($var, str_repeat ( '*' , strlen($var) - $charToKeep), $charToKeep) : $var;
Keep in mind that regex are good for matching patterns in string, but there is a lot of functions already designed for string manipulation.
Will output:
abc***
Try this function. You can specify how much chars should be visible and which character should be used as mask:
$string = "abcd1234";
echo hideCharacters($string, 3, "*");
function hideCharacters($string, $visibleCharactersCount, $mask)
{
if(strlen($string) < $visibleCharactersCount)
return $string;
$part = substr($string, 0, $visibleCharactersCount);
return str_pad($part, strlen($string), $mask, STR_PAD_RIGHT);
}
Output:
abc*****
Your regex matches all symbols after the first 3, thus, you replace them with a one hard-coded *.
You can use
'~(^.{3}|(?!^)\G)\K.~'
And replace with *. See the regex demo
This regex matches the first 3 characters (with ^.{3}) or the end of the previous successful match or start of the string (with (?!^)\G), and then omits the characters matched from the match value (with \K) and matches any character but a newline with ..
See IDEONE demo
$re = '~(^.{3}|(?!^)\G)\K.~';
$strs = array("aa","apple", "google", "abc12345", "asdddd");
foreach ($strs as $s) {
$result = preg_replace($re, "*", $s);
echo $result . PHP_EOL;
}
Another possible solution is to concatenate the first three characters with a string of * repeated the correct number of times:
$text = substr($string, 0, 3).str_repeat('*', max(0, strlen($string) - 3));
The usage of max() is needed to avoid str_repeat() issue a warning when it receives a negative argument. This situation happens when the length of $string is less than 3.

PHP wrapping last two letters of string with HTML

I am running into a problem trying to do a replacement on a few strings. Essentially what I have is a bunch of prices on my page that look like
RMB148.00
What i am trying to do is run a replace on only the last 2 numbers so i can do something like
RMB14800
Preg replace works fine for the RMB part because it is always there.
My problem is the last two numbers can be anything it all depends on the price so I cant just remove and replace, I need to just wrap HTML <sup> tags around them.
$string = $product['price'];
$string = preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $string);
echo preg_replace('/RMB/', '<sup class="currency-sym">RMB</sup>', $string, 1);
Assuming the last two characters are digits, you could just
$string=preg_replace('/(\d\d)$/', '<sup class="currency-sym">\1</sup>', $string);
If not,
$string=preg_replace('/(..)$/', '<sup class="currency-sym">\1</sup>', $string);
should do the trick.
Alternativly use
$string=substr($string,0,-2).'<sup class="currency-sym">'.substr($string,-2).'</sup>';
Here is a regex solution that looks for the final digit notation at the end of your string.
$string = 'RMB148.00';
$string = preg_replace('/(\d+)\.(\d{2})\z/','$1<sup>$2</sup>',$string);
echo $string;
You could use the following with the explode () function
$string = explode ('.', $product['price']);
$new_string = $string[0].'<sup>'. $string [1]. '</sup>';
And do the regex for the RMB the same way.
Code.
<?php
$string = '14842.00';
$string = substr($string, 0, strlen($string) - 2) . '<sup>' . substr($string, strlen($string) - 2, 2) . '</sup>';
echo $string;
Try online sandbox.
Explanation.
substr($s, $i, $l) gets $l symbols of $s, started from $i index (indexes starts from zero).
So first substr($string, 0, strlen($string) - 2) gets all string except last two symbols.
Second substr($string, strlen($string) - 2, 2) gets only last two symbols.
More about substr.
You should use a pattern matching regex. Note the $1 in the replacement argument matches (\d{2}) in the pattern argument. preg_replace() only replaces the matched pattern. This pattern matches . followed by any two digits. Since . is not included in the replacement argument it does not show up in your $string.
$string = preg_replace('/\.(\d{2})$/', '<sup>$1</sup>', $string);
Of course, you could use one preg_replace to do what you want:
$string = preg_replace('/^(RMB)(\d+)(\.(\d{2}))?$/', "<sup class='currency-sym'>$1</sup>$2<sup>$4</sup>", $string);
The second example may be a good idea if you want DOM integrity, otherwise it creates an empty <sup></sup> when there is no decimal.

Unicode (UTF8) string word count in PHP

I need to have the word count of the following unicode string. Using str_word_count:
$input = 'Hello, chào buổi sáng';
$count = str_word_count($input);
echo $count;
the result is
7
which is aparentley wrong.
How to get the desired result (4)?
$tags = 'Hello, chào buổi sáng';
$word = explode(' ', $tags);
echo count($word);
Here's a demo: http://codepad.org/667Cr1pQ
Here is a quick and dirty regex-based (using Unicode) word counting function:
function mb_count_words($string) {
preg_match_all('/[\pL\pN\pPd]+/u', $string, $matches);
return count($matches[0]);
}
A "word" is anything that contains one or more of:
Any alphabetic letter
Any digit
Any hyphen/dash
This would mean that the following contains 5 "words" (4 normal, 1 hyphenated):
echo mb_count_words('Hello, chào buổi sáng, chào-sáng');
Now, this function is not well suited for very large texts; though it should be able to handle most of what counts as a block of text on the internet. This is because preg_match_all needs to build and populate a big array only to throw it away once counted (it is very inefficient). A more efficient way of counting would be to go through the text character by character, identifying unicode whitespace sequences, and incrementing an auxiliary variable. It would not be that difficult, but it is tedious and takes time.
You may use this function to count unicode words in given string:
function count_unicode_words( $unicode_string ){
// First remove all the punctuation marks & digits
$unicode_string = preg_replace('/[[:punct:][:digit:]]/', '', $unicode_string);
// Now replace all the whitespaces (tabs, new lines, multiple spaces) by single space
$unicode_string = preg_replace('/[[:space:]]/', ' ', $unicode_string);
// The words are now separated by single spaces and can be splitted to an array
// I have included \n\r\t here as well, but only space will also suffice
$words_array = preg_split( "/[\n\r\t ]+/", $unicode_string, 0, PREG_SPLIT_NO_EMPTY );
// Now we can get the word count by counting array elments
return count($words_array);
}
All credits go to the author.
I'm using this code to count word. You can try this
$s = 'Hello, chào buổi sáng';
$s1 = array_map('trim', explode(' ', $s));
$s2 = array_filter($s1, function($value) { return $value !== ''; });
echo count($s2);

Extract last section of string

I have a string like this:
[numbers]firstword[numbers]mytargetstring
I would like to know how is it possible to extract "targetstring" taking account the following :
a.) Numbers are numerical digits for example, my complete string with numbers:
12firstword21mytargetstring
b.) Numbers can be any digits, for example above are two digits each, but it can be any number of digits like this:
123firstword21567mytargetstring
Regardless of the number of digits, I am only interested in extracting "mytargetstring".
By the way "firstword" is fixed and will not change with any combination.
I am not very good in Regex so I appreciate someone with strong background can suggest how to do this using PHP. Thank you so much.
This will do it (or should do)
$input = '12firstword21mytargetstring';
preg_match('/\d+\w+\d+(\w+)$/', $input, $matches);
echo $matches[1]; // mytargetstring
It breaks down as
\d+\w+\d+(\w+)$
\d+ - One or more numbers
\w+ - followed by 1 or more word characters
\d+ - followed by 1 or more numbers
(\w+)$ - followed by 1 or more word characters that end the string. The brackets mark this as a group you want to extract
preg_match("/[0-9]+[a-z]+[0-9]+([a-z]+)/i", $your_string, $matches);
print_r($matches);
You can do it with preg_match and pattern syntax.
$string ='2firstword21mytargetstring';
if (preg_match ('/\d(\D*)$/', $string, $match)){
// ^ -- end of string
// ^ -- 0 or more
// ^^ -- any non digit character
// ^^ -- any digit character
var_dump($match[1]);}
Try it like,
print_r(preg_split('/\d+/i', "12firstword21mytargetstring"));
echo '<br/>';
echo 'Final string is: '.end(preg_split('/\d+/i', "12firstword21mytargetstring"));
Tested on http://writecodeonline.com/php/
You don't need regex for that:
for ($i=strlen($string)-1; $i; $i--) {
if (is_numeric($string[$i])) break;
}
$extracted_string = substr($string, $i+1);
Above it's probably the faster implementation you can get, certainly faster than using regex, which you don't need for this simple case.
See the working demo
your simple solution is here :-
$keywords = preg_split("/[\d,]+/", "hypertext123language2434programming");
echo($keywords[2]);

Categories