10

I am trying to write a function to clean up user input.

I am not trying to make it perfect. I would rather have a few names and acronyms in lowercase than a full paragraph in uppercase.

I think the function should use regular expressions but I'm pretty bad with those and I need some help.

If the following expressions are followed by a letter, I want to make that letter uppercase.

 "."
 ". " (followed by a space)
 "!"
 "! " (followed by a space)
 "?"
 "? " (followed by a space)

Even better, the function could add a space after ".", "!" and "?" if those are followed by a letter.

How this can be achieved?

kenorb
  • 155,785
  • 88
  • 678
  • 743
Enkay
  • 1,898
  • 6
  • 24
  • 35

7 Answers7

33
$output = preg_replace('/([.!?])\s*(\w)/e', "strtoupper('\\1 \\2')", ucfirst(strtolower($input)));

Since the modifier e is deprecated in PHP 5.5.0:

$output = preg_replace_callback('/([.!?])\s*(\w)/', function ($matches) {
    return strtoupper($matches[1] . ' ' . $matches[2]);
}, ucfirst(strtolower($input)));
w35l3y
  • 8,613
  • 3
  • 39
  • 51
  • @w35l3y your code interest me... but How to do if my string is with some tags like that for example : `hello. this doesn' work !` ... ? can you improve your code please for this kind of case ? In fact, how to escape `` without delete them ? thank you :) – Zagloo Mar 31 '15 at 10:14
  • @Zagloo, in the case above, it is a requirement to have just 1 space independently of the current number of spaces. In your case, it is subject to a new question. Consider asking a new one and let me know. In short, I don't have good news for you because a `span` without any attribute is easy, but what about nested nodes with various attributes each? – w35l3y Mar 31 '15 at 18:10
  • @w35l3y Thx for your return ! I made a new post yesterday and someone found the solution here : http://stackoverflow.com/questions/29366592/php-improve-text-capitalization-function/29367216#29367216 ;o) – Zagloo Apr 01 '15 at 06:54
  • Hello. I don't understand the part `[.!?] `of the regular expression. Isn't the unescaped dot expected to match ANY character (including "!" and "?")? I think it should be escaped but this answer has been here a lot of time... – NeDark Aug 27 '16 at 23:30
  • @NeDark, in a `[]` block any character except `-^\]` is a literal. – w35l3y Aug 30 '16 at 20:23
3

Here is the code that does as you wanted:

<?php

$str = "paste your code! below. codepad will run it. are you sure?ok";

//first we make everything lowercase, and 
//then make the first letter if the entire string capitalized
$str = ucfirst(strtolower($str));

//now capitalize every letter after a . ? and ! followed by space
$str = preg_replace_callback('/[.!?] .*?\w/', 
  create_function('$matches', 'return strtoupper($matches[0]);'), $str);

//print the result
echo $str . "\n";
?>

OUTPUT: Paste your code! Below. Codepad will run it. Are you sure?ok

anubhava
  • 761,203
  • 64
  • 569
  • 643
1

How about this? Without Regex.

$letters = array(
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'
);
foreach ($letters as $letter) {
    $string = str_replace('. ' . $letter, '. ' . ucwords($letter), $string);
    $string = str_replace('? ' . $letter, '? ' . ucwords($letter), $string);
    $string = str_replace('! ' . $letter, '! ' . ucwords($letter), $string);
}

Worked fine for me.

Walt
  • 11
  • 2
1

Separate string into arrays using ./!/? as delimeter. Loop through each string and use ucfirst(strtolower($currentString)), and then join them again into one string.

David Thomas
  • 249,100
  • 51
  • 377
  • 410
chojnovsky
  • 11
  • 1
  • Interesting take. I'll give it a try. I was hoping to practice my regex a little but this could get the job done. Thank you. – Enkay Mar 21 '11 at 21:04
1

This:

<?
$text = "abc. def! ghi? jkl.\n";
print $text;
$text = preg_replace("/([.!?]\s*\w)/e", "strtoupper('$1')", $text);
print $text;
?>

Output:
abc. def! ghi? jkl.
abc. Def! Ghi? Jkl.

Note that you do not have to escape .!? inside [].

Damon
  • 67,688
  • 20
  • 135
  • 185
0
$output = preg_replace('/([\.!\?]\s?\w)/e', "strtoupper('$1')", $input)
Sony Santos
  • 5,435
  • 30
  • 41
  • preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead – Sylar Apr 26 '21 at 12:17
-2
$Tasks=["monday"=>"maths","tuesday"=>"physics","wednesday"=>"chemistry"];

foreach($Tasks as $task=>$subject){

     echo "<b>".ucwords($task)."</b> : ".ucwords($subject)."<br/>";
}
Yuca
  • 6,010
  • 3
  • 22
  • 42