I want to CaPiTaLiZe $string in php, don't ask why :D
I made some research and found good answers here, they really helped me.
But, in my case I want to start capitalizing every odd character (1,2,3...) in EVERY word.
For example, with my custom function i'm getting this result "TeSt eXaMpLe" and want to getting this "TeSt ExAmPlE".
See that in second example word "example" starts with capital "E"?
So, can anyone help me? : )
Well I would just make it an array and then put it back together again.
<?php
$str = "test example";
$str_implode = str_split($str);
$caps = true;
foreach($str_implode as $key=>$letter){
if($caps){
$out = strtoupper($letter);
if($out <> " ") //not a space character
$caps = false;
}
else{
$out = strtolower($letter);
$caps = true;
}
$str_implode[$key] = $out;
}
$str = implode('',$str_implode);
echo $str;
?>
Demo: http://codepad.org/j8uXM97o
I would use regex to do this, since it is concise and easy to do:
$str = 'I made some research and found good answers here, they really helped me.';
$str = preg_replace_callback('/(\w)(.?)/', 'altcase', $str);
echo $str;
function altcase($m){
return strtoupper($m[1]).$m[2];
}
Outputs: "I MaDe SoMe ReSeArCh AnD FoUnD GoOd AnSwErS HeRe, ThEy ReAlLy HeLpEd Me."
Example
Here's a one liner that should work.
preg_replace('/(\w)(.)?/e', "strtoupper('$1').strtolower('$2')", 'test example');
http://codepad.org/9LC3SzjC
Try:
function capitalize($string){
$return= "";
foreach(explode(" ",$string) as $w){
foreach(str_split($w) as $k=>$v) {
if(($k+1)%2!=0 && ctype_alpha($v)){
$return .= mb_strtoupper($v);
}else{
$return .= $v;
}
}
$return .= " ";
}
return $return;
}
echo capitalize("I want to CaPiTaLiZe string in php, don't ask why :D");
//I WaNt To CaPiTaLiZe StRiNg In PhP, DoN'T AsK WhY :D
Edited: Fixed the lack of special characters in the output.
This task can be performed without using capture groups -- just use ucfirst().
This is not built to process multibyte characters.
Grab a word character then, optionally, the next character. From the fullstring match, only change the case of the first character.
Code: (Demo) (or Demo)
$strings = [
"test string",
"lado lomidze needs a solution",
"I made some research and found 'good' answers here; they really helped me."
]; // if not already all lowercase, use strtolower()
var_export(preg_replace_callback('/\w.?/', function ($m) { return ucfirst($m[0]); }, $strings));
Output:
array (
0 => 'TeSt StRiNg',
1 => 'LaDo LoMiDzE NeEdS A SoLuTiOn',
2 => 'I MaDe SoMe ReSeArCh AnD FoUnD \'GoOd\' AnSwErS HeRe; ThEy ReAlLy HeLpEd Me.',
)
For other researchers, if you (more simply) just want to convert every other character to uppercase, you could use /..?/ in your pattern, but using regex for this case would be overkill. You could more efficiently use a for() loop and double-incrementation.
Code (Demo)
$string = "test string";
for ($i = 0, $len = strlen($string); $i < $len; $i += 2) {
$string[$i] = strtoupper($string[$i]);
}
echo $string;
// TeSt sTrInG
// ^-^-^-^-^-^-- strtoupper() was called here
Related
I have some string:
It's not big deal
I want to change it to
It's not_big deal
So far, I try this code but return "undefined offset: $y"
function checkNegation($word){
$input = strtolower($word);
$split = preg_split('/\s+/', $input);
$length = count($split);
$neg = "NOT_";
for ($x=0; $x<$length; $x++){
if (preg_match("/\bNOT\b/i",$split[$x])){
$y=$x+1;
$split[$x] = "{$neg}{$split[$y]}";
unset($split[$y]);
}
}
$word = implode(" ",$split);
return $word;
}
can you help me? thank you :')
Why not just preg_replace?
$str = "It's not big deal";
echo preg_replace("/\b(not)\s+/i", "$1_", $str); // It's not_big deal
if you're using regex already, why do you need to break the string into array of words? you can just match "not" in it and replace it with "not_". why over-complicate things?
your program seems to be running fine. but it'll cause problem if the word "not" is the last word in the string. because in that case, $y will go out of array range.
I'm trying to retrieve the first and last sentences from database text entries.
The code I have works fine in this example:
$text = "He was doing ok so far, but this one had stumped him. He was a bit lost..."
The functions:
function first_sentence($content) {
$pos = strpos($content, '.');
if($pos === false) {
return $content;
}
else {
return substr($content, 0, $pos+1);
}
} // end function
// Get the last sentence
function last_sentence($content) {
$content = array_pop(array_filter(explode('.', $content), 'trim'));
return $content;
} // end function
The last sentence function takes into account any trailing...'s at the end of a sentence, but neither can cope with the following:
$text = "Dr. Know-all was a coding master, he knew everything and was reputed the world over. But the Dr. was in trouble..."
Result:
First sentence: Dr.
Last sentence: was in trouble
I need to modify the functions to take into account things like 'Dr.' and other such abbreviations if that's possible, so the last text variable would come out as:
First sentence: Dr. Know-all was a coding master, he knew everything and was reputed the world over
Last sentence: But the Dr. was in trouble
Can it be done? Any help much appreciated!
You can exclude some word by replacing them.
<?
function first_sentence($content) {
$pos = strpos($content, '.');
if($pos === false) {
return $content;
}
else {
return substr($content, 0, $pos+1);
}
} // end function
// Get the last sentence
function last_sentence($content) {
$content = array_pop(array_filter(explode('.', $content), 'trim'));
return $content;
} // end function
$text = "Dr. Know-all was a coding master, he knew everything and was reputed the world over. But the Dr. was in trouble...";
$tmp = str_replace("Dr.","Dr____",$text);
echo $tmm ."\n";
echo str_replace("Dr____","Dr.",first_sentence($tmp ))."\n";
echo str_replace("Dr____","Dr.",last_sentence($tmp ));
?>
WORKING CODE
Maybe you thought about that..
Can you make a function to encode/decode the $content before you search for the sentences;
function encode_content($content){
return $encoded_content = str_replace("Dr.", "Dr#;#", $content);
}
And after you retrieve the sentences, decode again:
function decode_content($content){
return $encoded_content = str_replace("Dr#;#", "Dr." , $content);
}
You can check your substr length, and return only if it is longer than 3 characters (point included). If it is less or equal, you can use a whitelist in order not to stumble upon words such as "No", "Me", "Us", "Oh"... Scrabble dictionaries should be able to help you there :)
Just to answer my own question after putting some new functions together given the answers so far
function encode_text($content){
$search = array("Dr.", "i.e.", "Mr.", "Mrs.", "Ms."); // put our potential problems in an array
$replace = array("Dr#;#", "i#e#", "Mr#;#", "Mrs#;#", "Ms#;#"); // make them good for first and last sentence functions
$encoded_content = str_replace($search, $replace, $content);
return $encoded_content;
} // end encode
Then we just swap the search and replace variables around to make our decode function. Now they can be used with the first and last sentence functions above, and it works a charm. Adding stuff to the arrays is simple, thinking of what's appropriate to add tho is less so :)
Cheers!
We want to censor certain words on our site but each word has different censored output.
For example:
PHP => P*P, javascript => j*vascript
(However not always the second letter.)
So we want a simple "one star" censor system but with keeping the original caps. The datas coming from the database are uncensored so we need the fastest way that possible.
$data="Javascript and php are awesome!";
$word[]="PHP";
$censor[]="H";//the letter we want to replace
$word[]="javascript";
$censor[]="a"//but only once (j*v*script would look wierd)
//Of course if it needed we can use the full censored word in $censor variables
Expected value:
J*vascript and p*p are awesome!
Thanks for all the answers!
You can put your censored words in key-based array, and value of the array should be the position of what char is replaced with * (see $censor array example bellow).
$string = 'JavaSCRIPT and pHp are testing test-ground for TEST ŠĐČĆŽ ŠĐčćŽ!';
$censor = [
'php' => 2,
'javascript' => 2,
'test' => 3,
'šđčćž' => 4,
];
function stringCensorSlow($string, array $censor) {
foreach ($censor as $word => $position) {
while (($pos = mb_stripos($string, $word)) !== false) {
$string =
mb_substr($string, 0, $pos + $position - 1) .
'*' .
mb_substr($string, $pos + $position);
}
}
return $string;
}
function stringCensorFast($string, array $censor) {
$pattern = [];
foreach ($censor as $word => $position) {
$word = '~(' . mb_substr($word, 0, $position - 1) . ')' . mb_substr($word, $position - 1, 1) . '(' . mb_substr($word, $position) . ')~iu';
$pattern[$word] = '$1*$2';
}
return preg_replace(array_keys($pattern), array_values($pattern), $string);
}
Use example :
echo stringCensorSlow($string, $censor);
# J*vaSCRIPT and p*p are te*ting te*t-ground for TE*T ŠĐČ*Ž ŠĐč*Ž!
echo stringCensorFast($string, $censor) . "\n";
# J*vaSCRIPT and p*p are te*ting te*t-ground for TE*T ŠĐČ*Ž ŠĐč*Ž!
Speed test :
foreach (['stringCensorSlow', 'stringCensorFast'] as $func) {
$time = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$func($string, $censor);
}
$time = microtime(true) - $time;
echo "{$func}() took $time\n";
}
output on my localhost was :
stringCensorSlow() took 1.9752140045166
stringCensorFast() took 0.11587309837341
Upgrade #1: added multibyte character safe.
Upgrade #2: added example for preg_replace, which is faster than mb_substr. Tnx to AbsoluteƵERØ
Upgrade #3: added speed test loop and result on my local PC machine.
Make an array of words and replacements. This should be your fastest option in terms of processing, but a little more methodical to setup. Remember when you're setting up your patterns to use the i modifier to make each pattern case insensitive. You could ultimately pull these from a database into the arrays. I've hard-coded the arrays here for the example.
<!DOCTYPE html>
<html>
<meta content="text/html; charset=UTF-8" http-equiv="content-type">
<?php
$word_to_alter = array(
'!(j)a(v)a(script)(s|ing|ed)?!i',
'!(p)h(p)!i',
'!(m)y(sql)!i',
'!(p)(yth)o(n)!i',
'!(r)u(by)!i',
'!(ВЗЛ)О(М)!iu',
);
$alteration = array(
'$1*$2*$3$4',
'$1*$2',
'$1*$2',
'$1$2*$3',
'$1*$2',
'$1*$2',
);
$string = "Welcome to the world of programming. You can learn PHP, MySQL, Python, Ruby, and Javascript all at your own pace. If you know someone who uses javascripting in their daily routine you can ask them about becoming a programmer who writes JavaScripts. взлом прохладно";
$newstring = preg_replace($word_to_alter,$alteration,$string);
echo $newstring;
?>
</html>
Output
Welcome to the world of programming. You can learn P*P, M*SQL, Pyth*n,
R*by, and J*v*script all at your own pace. If you know someone who
uses j*v*scripting in their daily routine you can ask them about
becoming a programmer who writes J*v*Scripts. взл*м прохладно
Update
It works the same with UTF-8 characters, note that you have to specify a u modifier to make the pattern treated as UTF-8.
u (PCRE_UTF8)
This modifier turns on additional functionality of PCRE that is incompatible with Perl. Pattern strings are treated as UTF-8. This
modifier is available from PHP 4.1.0 or greater on Unix and from PHP
4.2.3 on win32. UTF-8 validity of the pattern is checked since PHP 4.3.5.
Why not just use a little helper function and pass it a word and the desired censor?
function censorWord($word, $censor) {
if(strpos($word, $censor)) {
return preg_replace("/$censor/",'*', $word, 1);
}
}
echo censorWord("Javascript", "a"); // returns J*avascript
echo censorWord("PHP", "H"); // returns P*P
Then you can check the word against your wordlist and if it is a word that should be censored, you can pass it to the function. Then, you also always have the original word as well as the censored one to play with or put back in your sentence.
This would also make it easy to change the number of letters censored by just changing the offset in the preg_replace. All you have to do is keep an array of words, explode the sentence on spaces or something, and then check in_array. If it is in the array, send it to censorWord().
Demo
And here's a more complete example doing exactly what you said in the OP.
function censorWord($word, $censor) {
if(strpos($word, $censor)) {
return preg_replace("/$censor/",'*', $word, 1);
}
}
$word_list = ['php','javascript'];
$data = "Javascript and php are awesome!";
$words = explode(" ", $data);
// pass each word by reference so it can be modified inside our array
foreach($words as &$word) {
if(in_array(strtolower($word), $word_list)) {
// this just passes the second letter of the word
// as the $censor argument
$word = censorWord($word, $word[1]);
}
}
echo implode(" ", $words); // returns J*vascript and p*p are awesome!
Another Demo
You could store a lowercase list of the censored words somewhere, and if you're okay with starring the second letter every time, do something like this:
if (in_array(strtolower($word), $censored_words)) {
$word = substr($word, 0, 1) . "*" . substr($word, 2);
}
If you want to change the first occurrence of a letter, you could do something like:
$censored_words = array('javascript' => 'a', 'php' => 'h', 'ruby' => 'b');
$lword = strtolower($word);
if (in_array($lword, array_keys($censored_words))) {
$ind = strpos($lword, $censored_words[$lword]);
$word = substr($word, 0, $ind) . "*" . substr($word, $ind + 1);
}
This is what I would do:
Create a simple database (text file) and make a "table" of all your censored words and expected censored results. E.G.:
PHP --- P*P
javascript --- j*vascript
HTML --- HT*L
Write PHP code to compare the database information to your simple censored file. You will have to use array explode to create an array of only words. Something like this:
/* Opening database of censored words */
$filename = "/files/censored_words.txt";
$file = fopen( $filename, "r" );
if( $file == false )
{
echo ( "Error in opening file" );
exit();
}
/* Creating an array of words from string*/
$data = explode(" ", $data); // What was "Javascript and PHP are awesome!" has
// become "Javascript", "and", "PHP", "are",
// "awesome!". This is useful.
If your script finds matching words, replace the word in your data with the censored word from your list. You would have to delimit the file first by \r\n and finally by ---. (Or whatever you choose for separating your table with.)
Hope this helped!
I'm using PHP's preg_replace, and trying to transform the string
abcd
into
(a(b(c(d))))
This is the best I've got:
preg_replace('/.(?=(.*$))/', '$0($1)', 'abcd');
// a(bcd)b(cd)c(d)d()
Is it even possible with regex?
Edit I've just discovered this in the PCRE spec: Replacements are not subject to re-matching, so my original approach isn't going to work. I wanted to keep it all regex because there's some more complicated matching logic in my actual use case.
How about:
preg_replace('/./s', '($0', 'abcd') . str_repeat(')', strlen('abcd'));
?
(Does that count as "with regex"?)
You can use preg_match_all. Not sure what kind of characters you want, though. So I'll give an example for all characters:
$val = 'abcd1234';
$out = '';
if(preg_match_all('#.#', $val, $matches))
{
$i = 0; // we'll use this to keep track of how many open paranthesis' we have
foreach($matches[0] as &$v)
{
$out .= '('.$v;
$i++;
}
$out .= str_repeat(")", $i);
}
else
{
// no matches found or error occured
}
echo $out; // (a(b(c(d(1(2(3(4))))))))
Will be easy to customise further, as well.
This is my way to do it =) :
<?php
$arr = str_split("abcd");
$new_arr = array_reverse($arr);
foreach ($new_arr as $a) {
$str = sprintf('(%s%s)', $a, $str);
}
echo "$str\n";
?>
KISS isn't it ? (few lines : 6)
I went with something along the lines of a combination of the above answers:
preg_match_all('/./ui', 'abcd', $matches);
$matches = $matches[0];
$string = '('.implode('(', $matches).str_repeat(')', count($matches));
I would like to change a string in php from all upper case to normal cases. So that every sentence would start with an upper case and the rest would be in lower case.
Is there a simple way to do this ?
A simple way is to use strtolower to make the string lower case, and ucfirst to upper case the first char as follows:
$str=ucfirst(strtolower($str));
If the string contains multiple sentences, you'll have to write your own algorithm, e.g. explode on sentence separators and process each sentence in turn. As well as the first char, you might need some heuristics for words like "I" and any common proper nouns which appear in your text. E.g, something like this:
$sentences=explode('.', strtolower($str));
$str="";
$sep="";
foreach ($sentences as $sentence)
{
//upper case first char
$sentence=ucfirst(trim($sentence));
//now we do more heuristics, like turn i and i'm into I and I'm
$sentence=preg_replace('/i([\s\'])/', 'I$1', $sentence);
//append sentence to output
$str=$sep.$str;
$sep=". ";
}
Here's a function that will do it:
function sentence_case($s) {
$str = strtolower($s);
$cap = true;
for($x = 0; $x < strlen($str); $x++){
$letter = substr($str, $x, 1);
if($letter == "." || $letter == "!" || $letter == "?"){
$cap = true;
}elseif($letter != " " && $cap == true){
$letter = strtoupper($letter);
$cap = false;
}
$ret .= $letter;
}
return $ret;
}
Source:
http://codesnippets.joyent.com/posts/show/715
I don't know of any method that will do this automatically. You would probably have to write your own with rules that would take of special cases like the letter 'i' needing to be capitalized when it is on its own. You would also still miss out on the ability to capitalize things like people and place names.
Perfectly possible
$s = "THIS IS THE LINE I'M GOING TO WORK ON";
$s = ucfirst(strtolower($s));
echo $s; //This is the line I'm going to work on
If the string contains only 1 sentence then you could use:
$string = ucfirst(strtolower($string));
Point to keep in mind: Do not apply this to all input fields!
People with ALL CAPS initials in their names can get mighty annoyed if you turn "Mike DF King" into "Mike Df King"
cheers :)