From the course: PHP Tips, Tricks, and Techniques
Smart quotes and apostrophes
From the course: PHP Tips, Tricks, and Techniques
Smart quotes and apostrophes
- [David] Hi, I'm David Powers, and welcome to this week's edition of PHP Tips, Tricks, and Techniques designed to help you become a smarter, more productive PHP developer. This week's technique is something that should appear to typographers, smart quotes and apostrophes. In other words, converting straight quotes in texts to curly quotes. I've got an example in this file. The string at the top of the script contains a combination of double and single straight quotes. But some of the straight quotes are apostrophes like this one here. And then at the end of the sentence we've got a particular challenge. We've got some straight quotes surrounding the title of the play, but in the middle there's an apostrophe. And on line six I define a function called smart quotes which takes a single argument, the text where you want to convert the straight quotes into curly quotes. I'll come back to how it works in a moment. But if I scroll down to the bottom we can see here that in the HTML on line 30 I'm passing that string to the smart quotes function and then outputting it. So let's load this page into a browser to see the result. I'll just zoom in a little bit so we can see it more clearly. The opening and the closing quotes, they've been paired correctly. We've got some more opening double quotes here and then we've got an apostrophe. That looks good. That apostrophe also looks good. And then this challenge at the bottom here, we've got an opening single quote there, we've got the apostrophe in the middle, that's correct, and we've also got the closing right hand quote there. They all look good. So let's return to my editing program to see how the smart quotes function works. We'll scroll back up and take a look at it. Lines seven through to 13 define a series of variables that look rather like Klingon poetry. Then on lines 15 and 16 they're assigned to a couple of arrays called patterns and replacements. And these in turn are passed as arguments to the preg_replace function. Preg_replace uses Perl compatible regular expressions to match patterns in a string and replace them. And a really useful feature is that you can use arrays for both the patterns and for the replacements. So anything in the string passed to preg_replace that matches the first regular expression, in other words double quotes, will be replaced by double replace. So up here, double quotes is a regular expression, and double replace is the replacement, and it uses unicode code points. Then anything that matches ls_quote will be replaced by ls_replace. And anything that matches apostrophe is replaced by rs_replace and then finally rs_quote. Anything that matches that is replaced by rs_replace again. So what about all of this Klingon poetry? Well, if regular expressions give you a headache, spare a thought for me. I had to work all this out in the first place. And if regular expressions are a complete mystery to you, check out Kevin Skoglund's in-depth course Learning Regular Expressions. I'm just gonna concentrate on what we have here. Let's start with double quotes. This is the regular expression that matches pairs of opening and closing quotes and everything in between. It begins with a double quote in parentheses, so it matches a literal double quote and nothing else. The parentheses make it a capturing pattern. Then we've added another capturing pattern with a character class in square brackets that matches anything except a double quote. The plus and question mark make the character class non-greedy. So this matches and captures everything up to the matching closing quote. The backslash one matches whatever was captured in the first capturing group, in other words, another double quote. The replacement string is in double quotes because it contains escape sequences. Backslash u 201C is the unicode code point for an opening double quote. $2 represents everything captured by the second capturing group. In other words, everything between the opening and closing quotes. Then we replace the closing quote with the unicode code point for a closing double quote. Next we deal with left single quotes. This is the regular expression that matches them. The first part of the regex is a negative look behind with backslash w, the shorthand for a word character. So this won't match anything that begins with a character that can appear in a word. It's followed by a literal single quote and a positive look ahead, again with backslash w. So whatever follows the single quote must be part of a word. The replacement string is the unicode code point for a left single quote. The parentheses around the look behinds and look aheads don't form capturing groups. So this simply replaces the straight single quote. Next we deal with the apostrophe. The regular expression is very similar to the one for the single left quote. It beings with positive look behind for a word character, followed by a single quote and a positive look ahead for a word character. In other words, this is looking for a single quote between two word characters. This won't match an apostrophe at the end of a word, but that case is taken care of by the pattern by a right single quote. The replacement text is the unicode code point for a right single quote. And that replaces the single straight quote that's been matched. Finally, right single quotes. This is the regular expression. It begins with a positive look behind. The character class matches word characters and some punctuation. Then a single straight quote followed by a negative look ahead that won't match any character that can appear in a word. The replacement character is the same as for an apostrophe. It inserts a right single quote in place of the straight one. That was really some heavy lifting with regular expressions. In this version of the smart quotes function I've assigned the regular expressions and replacement strings to variables for ease of identification. But in this other file, optimized.php, I've passed them directly as arrays to preg_replace. This produces identical results to the more verbose version. Now I can't guarantee it will work in absolutely every situation where you want to replace straight quotes with curly ones, but I think it's fairly robust. Let me know if you find situations where it fails. Well that's it for this week. I hope you found it useful and that the Klingon poetry didn't give you too big a headache. 'Til next time, thanks for watching.
Practice while you learn with exercise files
Download the files the instructor uses to teach the course. Follow along and learn by watching, listening and practicing.
- Tip_18.zip
- Tip_19.zip
- Tip_01.zip
- Tip_20.zip
- Tip_02.zip
- Tip_25.zip
- Tip_03.zip
- Tip_21.zip
- Tip_22.zip
- Tip_04.zip
- Tip_23.zip
- Tip_24.zip
- Tip_06.zip
- Tip_07.zip
- Tip_34.zip
- Tip_30.zip
- Tip_31.zip
- Tip_14.zip
- Tip_32.zip
- Tip_17.zip
- Tip_33.zip
- Tip_29.zip
- Tip_35.zip
- Tip_36.zip
- Tip_37.zip
- Tip_09.zip
- Tip_10.zip
- Tip_38.zip
- Tip_39.zip
- Tip_40.zip
- Tip_08.zip
- Tip_26.zip
- Tip_11.zip
- Tip_12.zip
- Tip_13.zip
- Tip_15.zip
- Tip_16.zip
- Tip_28.zip
Contents
-
-
-
Round numbers to a specific multiple6m 57s
-
Array dereferencing4m 55s
-
Variable functions6m 8s
-
Build nested unordered lists automatically8m 56s
-
Display a repeating value only once4m 43s
-
Batch convert images to data URIs8m 18s
-
Multiple string replacement and SVGs8m 45s
-
Prevent cross-site script attacks in forms9m 39s
-
Changes to calculations with strings7m 35s
-
Unpacking arrays in PHP 7.17m 46s
-
User authentication with password hashing9m 20s
-
Set a future date7m 40s
-
Block access to expired member10m 55s
-
Extract complete sentences from start of text8m 48s
-
Prevent email header injection attacks7m 17s
-
Variable variables6m 47s
-
Select files for archiving9m 58s
-
Set a time limit on a session7m 27s
-
Custom sort an array with the spaceship operator7m 26s
-
Understanding the splat operator8m 55s
-
Converting new lines to real paragraphs7m 36s
-
Introducing PHP generators9m 33s
-
Dynamically editing a CSV file9m 32s
-
Finding all links in a webpage7m 35s
-
Creating a download link9m 45s
-
Debugging PDO prepared statements5m 59s
-
Time is running out for PHP 54m 43s
-
Extract values with a format string9m 10s
-
Generate harmonious color tones8m 7s
-
Getting all possible permutations of an array5m 39s
-
Merging arrays5m 57s
-
Strip accents from text9m 29s
-
Export associative arrays from a CSV6m 57s
-
Export spreadsheet data to a multi-table database10m 38s
-
Validate email address with accented characters3m 33s
-
Generating random numbers and strings7m 54s
-
Shorthand conditional expressions9m 9s
-
Modifying each element in an array8m 36s
-
Smart quotes and apostrophes7m 52s
-
Shortest distance between two locations6m 55s
-