Beginning PHP 5.3 phần 8 ppt

85 337 0
Beginning PHP 5.3 phần 8 ppt

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

558 Part III: Using PHP in Practice You can also pass an array of target strings for preg_replace() to work on, much like using preg_grep() . If you do this, preg_replace() returns the array of strings with any matched text replaced by the replacement text: $text = array( “Mouse mat: $3.99”, “Keyboard cover: $4.99”, “Screen protector: $5.99” ); $newText = preg_replace( “/\\$\d+\.\d{2}/”, “Only $0”, $text ); echo “ < pre > ”; print_r( $newText ); echo “ < /pre > ”; This code displays: Array ( [0] = > Mouse mat: Only $3.99 [1] = > Keyboard cover: Only $4.99 [2] = > Screen protector: Only $5.99 ) preg_replace() has a couple more tricks up its sleeve. You can pass an array of regular expression strings to the function, and it will match and replace each expression in turn with the replacement string: $text = “The wholesale price is $89.50. “ . “The product will be released on Jan 16, 2010.”; $patterns = array( “/\\$\d+\.\d{2}/”, “/\w{3} \d{1,2}, \d{4}/” ); echo preg_replace( $patterns, “[CENSORED]”, $text ); This script outputs the following: The wholesale price is [CENSORED]. The product will be released on [CENSORED]. If you also pass an array of replacement strings, the matched text from each expression in the expressions array is replaced by the corresponding string in the replacements array: $text = “The wholesale price is $89.50. “ . “The product will be released on Jan 16, 2010.”; $patterns = array( “/\\$\d+\.\d{2}/”, “/\w{3} \d{1,2}, \d{4}/” ); c18.indd 558c18.indd 558 9/21/09 6:17:59 PM9/21/09 6:17:59 PM Chapter 18: String Matching with Regular Expressions 559 $replacements = array( “[PRICE CENSORED]”, “[DATE CENSORED]” ); echo preg_replace( $patterns, $replacements, $text ); This script displays: The wholesale price is [PRICE CENSORED]. The product will be released on [DATE CENSORED]. If your replacements array contains fewer elements than your expressions array, matched text for any expression without a corresponding replacement is replaced with an empty string. For example: $text = “The wholesale price is $89.50. “ . “The product will be released on Jan 16, 2010.”; $patterns = array( “/\\$\d+\.\d{2}/”, “/\w{3} \d{1,2}, \d{4}/” ); $replacements = array( “[PRICE CENSORED]” ); echo preg_replace( $patterns, $replacements, $text ); displays: The wholesale price is [PRICE CENSORED]. The product will be released on . preg_replace() supports two more optional arguments. The first argument, an integer, lets you restrict how many times the pattern (or patterns) is replaced in the target string (or strings): // Displays “71%, 83%” echo preg_replace( “/\d+\%(,| )*/”, “”, “14%, 59%, 71%, 83%”, 2 ); This pattern replaces a percentage figure (followed optionally by commas and spaces) with an empty string. Because a limit argument of 2 was supplied, only the first two matches are replaced. The second optional argument is a variable to hold the number of replacements performed. (If you want to use this argument but you don ’ t want to limit the number of replacements, pass – 1 for the previous argument.) The following example replaces the character ‘ % ’ with the string “ percent ” four times, and displays the number of replacements: preg_replace( “/\%/”, “ percent”, “14%, 59%, 71%, 83%”, -1, $count ); echo $count; // Displays “4” The number stored in $count is the total number of replacements performed. So if you pass an array of 10 target strings and text is replaced once in five of them, then $count equals 5. c18.indd 559c18.indd 559 9/21/09 6:17:59 PM9/21/09 6:17:59 PM 560 Part III: Using PHP in Practice Replacing Text using a Callback Function preg_replace() is a powerful, flexible function, offering a multitude of ways to search and replace text. However, if you need even more flexibility you can use preg_replace_callback() , which lets you create a callback function to handle the replacement side of the operation. preg_replace_callback() works in much the same way as preg_replace() , and accepts all the same arguments, except that instead of passing a replacement string (or array of strings) as the second argument, you pass the name of your callback function as a string. Your callback function needs to accept an array of matches. The first element of the array (at index 0 ) contains the whole matched text, and additional elements contain any matched subpatterns. The string that your function returns is then used as the replacement text. Here ’ s an example. Say you have a large amount of sales copy that mentions prices of various products in your online store, and you want to increase all your product prices by a dollar. You can ’ t do arithmetic in regular expressions, but you can use preg_replace_callback() and a callback function to add numbers together: $text = “Our high-quality mouse mat is just $3.99, while our keyboard covers sell for $4.99 and our screen protectors for only $5.99.”; function addADollar( $matches ) { return “$” . ( $matches[1] + 1 ); } echo preg_replace_callback( “/\\$(\d+\.\d{2})/”, “addADollar”, $text ); The addADollar() callback function takes the second element in the matches array, which contains the matched text from the subpattern in the regular expression (that is, the price without the dollar symbol), and adds one to it. It returns this new value, preceded by a dollar symbol. This string is then used by preg_replace_callback() to replace the matched text, producing the following result: Our high-quality mouse mat is just $4.99, while our keyboard covers sell for $5.99 and our screen protectors for only $6.99. Altering Matching Behavior with Pattern Modifiers By placing a single letter, known as a pattern modifier , directly after the closing delimiter of a regular expression, you can change the way that the expression behaves. Here ’ s a list of the more useful modifiers: c18.indd 560c18.indd 560 9/21/09 6:18:00 PM9/21/09 6:18:00 PM Chapter 18: String Matching with Regular Expressions 561 Modifier Description i Causes the matching to be case insensitive: letters in the pattern match both upper - and lowercase characters in the string m Causes the target string to be treated as separate lines of text if it contains newlines. This means that ^ and $ characters in the expression match not only the beginning and end of the string, but also the beginning and end of each line in the string s Normally, the dot ( . ) character in an expression matches any character except newline characters. By adding this modifier you can make the dot character match newlines too x This modifier causes whitespace characters in the pattern to be ignored, rather than treated as characters to match. (However, whitespace inside a character class is never ignored.) This allows you to split your regular expression over lines and indent it, much like regular PHP code, to aid readability. You can also include comments in the expression by preceding them with a # symbol. If you explicitly want to match whitespace characters when using this modifier, use “ \ “ (for a space), “ \t ” (for a tab), or “ \s ” (for any whitespace character) e Only used by preg_replace() . This modifier allows you to use PHP code in your replacement string. Any backreferences ( $1 , $2 , and so on) in the replacement string are first replaced by their matched text. Then the string is evaluated as PHP code, and the resulting expression used for the replacement U Inverts the “ greediness ” of quantifiers within the expression: any non - greedy quantifiers become greedy, and any greedy quantifiers become non - greedy For example, you can make an expression case insensitive by adding i after the closing delimiter of the expression: $text = “Hello, world!”; echo preg_match( “/hello/”, $text ) . “ < br / > ”; // Displays “0” echo preg_match( “/hello/i”, $text ) . “ < br / > ”; // Displays “1” The following example shows how the m modifier works. The first expression attempts to match the characters “ world! ” followed by the end of the string. Because “ world! ” is not at the end of the target string, the match fails. However, the second expression uses the m modifier. This causes the $ character to match the newline after “ world! ” : $text = “Hello, world!\nHow are you today?\n”; echo preg_match( “/world!$/”, $text ) . “ < br / > ”; // Displays “0” echo preg_match( “/world!$/m”, $text ) . “ < br / > ”; // Displays “1” The m modifier is useful if you ’ re working with a multiline string (such as that read from a file or database query) that you want to treat as multiple lines of text rather than as one long string. By adding the x modifier to your expression you can split the expression over multiple lines and add comments — very handy for complex expressions: c18.indd 561c18.indd 561 9/21/09 6:18:00 PM9/21/09 6:18:00 PM 562 Part III: Using PHP in Practice $text = “Andy scored 184 points, Rachel attained 198 points and Bert scored 112 points.”; $pattern = “/ (Andy|Rachel|Bert)\ # Only match people we know about (scored|attained)\ # Two words, same meaning (\d+) # The number of points scored /x”; preg_match_all( $pattern, $text, $matches ); for ( $i = 0; $i < count( $matches[0] ); $i++ ) { echo $matches[1][$i] . “: “ . $matches[3][$i] . “ < br / > ”; } This code produces the following output: Andy: 184 Rachel: 198 Bert: 112 Finally, here ’ s an example that uses the e modifier. This is the same example used in the preg_replace_callback() section earlier in the chapter, rewritten to use e instead: $text = “Our high-quality mouse mat is just $3.99, while our keyboard covers sell for $4.99 and our screen protectors for only $5.99.”; echo preg_replace( “/\\$(\d+\.\d{2})/e”, “’$’ . ($1 + 1)”, $text ); For each match, the PHP code within the replacement string displays a dollar symbol followed by the text from the subpattern match (the price) plus one. This results in the following output: Our high-quality mouse mat is just $4.99, while our keyboard covers sell for $5.99 and our screen protectors for only $6.99. You can combine several modifiers at once — just add the modifier letters one after the other: $text = “Hello, World!\nHow are you today?\n”; echo preg_match( “/world!$/im”, $text ) . “ < br / > ”; // Displays “1” You can see the full list of pattern modifiers at http://www.php.net/manual/en/reference .pcre.pattern.modifiers.php . Splitting a String with a Regular Expression The final regular expression function explored in this chapter is preg_split() . In Chapter 6 you studied the explode() function, which allows you to split a string into an array of substrings. You pass in a delimiter string (a comma, for example) and the target string is split at each place the delimiter is found. c18.indd 562c18.indd 562 9/21/09 6:18:00 PM9/21/09 6:18:00 PM Chapter 18: String Matching with Regular Expressions 563 preg_split() takes string splitting a stage further by letting you specify a regular expression for the delimiter. This gives you a lot more flexibility when deciding what to split a string on, and is very useful when you need to parse a string written in human - friendly form. Consider the following example: $text = “John Steinbeck, Franz Kafka and J.R.R. Tolkien”; $authors = preg_split( “/,\s*|\s+and\s+/”, $text ); echo “ < pre > ”; print_r( $authors ); echo “ < /pre > ”; This code splits up the input string into its individual author names. The regular expression matches either a comma followed by zero or more whitespace characters, or the word “ and ” surrounded by one or more whitespace characters. This means that, whenever one of these two patterns is found in the input string, the string is split at that point, producing this result: Array ( [0] = > John Steinbeck [1] = > Franz Kafka [2] = > J.R.R. Tolkien ) As with explode() , you can limit the number of array elements returned by passing an integer as the third argument to preg_split() . You can also control preg_split() ’ s behavior by passing some optional flags as the fourth argument: PREG_SPLIT_NO_EMPTY : Removes any empty substrings from the returned array. This is useful for removing unwanted substrings, as you see in a moment PREG_SPLIT_DELIM_CAPTURE : Causes any matched subpatterns in the delimiter expression to be returned in the array, as well as the string parts PREG_SPLIT_OFFSET_CAPTURE : This works much like preg_match() ’ s PREG_OFFSET_CAPTURE flag. When set, preg_split() returns an array of arrays, where each nested array contains two elements: the text of the extracted substring and its position in the original string To set multiple flags, combine them with the bitwise OR operator — for example: PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE . If you want to set one or more flags and don ’ t want to limit the number of elements returned, pass – 1 as the third argument. To see how useful PREG_SPLIT_NO_EMPTY can be, consider the following example: $text = “’hello’, ‘goodbye’”; $letters = preg_split( “/[‘, ]/”, $text ); echo “ < pre > ”; print_r( $letters ); echo “ < /pre > ”; ❑ ❑ ❑ c18.indd 563c18.indd 563 9/21/09 6:18:01 PM9/21/09 6:18:01 PM 564 Part III: Using PHP in Practice This code displays: Array ( [0] = > [1] = > hello [2] = > [3] = > [4] = > [5] = > goodbye [6] = > ) This is because the regular expression causes any of the apostrophe, comma, and space characters to be treated as delimiters. So the string is split right at the start and end because the first and last characters are delimiters, and is also split three times between “ hello ” and “ goodbye ” because preg_split() “ sees ” three empty strings between the apostrophe, comma, and space characters in the input string. Naturally these empty substrings are unwanted. By setting the PREG_SPLIT_NO_EMPTY flag you can easily remove these substrings from the resulting array: $text = “’hello’, ‘goodbye’”; $letters = preg_split( “/[‘, ]/”, $text, -1, PREG_SPLIT_NO_EMPTY ); echo “ < pre > ”; print_r( $letters ); echo “ < /pre > ”; This code produces the desired result: Array ( [0] = > hello [1] = > goodbye ) Try It Out Validate Form Input Regular expressions are often used to check that user input is of the correct format. For example, you can use a regular expression to determine if a user-supplied date field contains a correctly formatted date string, or if a supplied email address follows the standard rules for email addresses. This example script creates an order form for an imaginary company selling three product ranges: SuperWidgets (with product codes of “SWnn”, where “nn” is a two-digit number), MegaWidgets (with products codes of “MWnn”), and WonderWidgets (with product codes of “WWnn”). The user can enter his email address, phone number, and the product codes to order. The script then validates both the email address and phone number fields, and also converts any supplied, valid product codes to a more human-readable form to display to the user in the confirmation page. Save the following script as order_form.php in your document root folder. c18.indd 564c18.indd 564 9/21/09 6:18:01 PM9/21/09 6:18:01 PM Chapter 18: String Matching with Regular Expressions 565 <!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Strict//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd”> <html xmlns=”http://www.w3.org/1999/xhtml” xml:lang=”en” lang=”en”> <head> <title>Validating Order Form Fields</title> <link rel=”stylesheet” type=”text/css” href=”common.css” /> </head> <body> <h1>Validating Order Form Fields</h1> <?php if ( isset( $_POST[“submitted”] ) ) { processForm(); } else { displayForm(); } function displayForm() { ?> <h2>Please enter your order details below then click Send Order:</h2> <form action=”” method=”post” style=”width: 30em;”> <div> <input type=”hidden” name=”submitted” value=”1” /> <label for=”emailAddress”>Your Email Address:</label> <input type=”text” name=”emailAddress” id=”emailAddress” value=”” /> <label for=”phoneNumber”>Your Phone Number:</label> <input type=”text” name=”phoneNumber” id=”phoneNumber” value=”” /> <label for=” productCodes”>Product Codes to Order:</label> <input type=”text” name=”productCodes” id=”productCodes” value=”” /> <label> </label> <input type=”submit” name=”submitButton” value=”Send Order” /> </div> </form> <div style=”clear: both;”> </div> <p>(Separate product codes by commas. Codes are SW, MW, WW followed by 2 digits.)</p> <?php } function processForm() { $errorMessages = array(); $emailAddressPattern = “/ ^ # Start of string \w+((-|\.)\w+)* # Some word characters optionally separated by - or # . \@ [A-Za-z\d]+ # Domain name: some alphanumeric characters c18.indd 565c18.indd 565 9/21/09 6:18:02 PM9/21/09 6:18:02 PM 566 Part III: Using PHP in Practice ((-|\.)[A-Za-z\d]+)* # followed 0 or more times by (- or . and more # alphanums) \.[A-Za-z\d]+ # followed by a final dot and some alphanumerics $ # End of string /x”; $phoneNumberPattern = “/ ^ # Start of string ( # Optional area code followed by optional # separator: \(\d{3}\)[ ]? # Code with parentheses | # or \d{3}[ ]? # Code without parentheses )? \d{3} # Prefix [ ] # Hyphen or dot separator \d{4} # Line number $ # End of string /x”; $productCodePattern = “/^(SW|MW|WW)(\d{2})$/i”; if ( !preg_match( $emailAddressPattern, $_POST[“emailAddress”] ) ) $errorMessages[] = “Invalid email address”; if ( !preg_match( $phoneNumberPattern, $_POST[“phoneNumber”] ) ) $errorMessages[] = “Invalid phone number”; if ( $errorMessages ) { echo “<p>There was a problem with the form you sent:</p><ul>”; foreach ( $errorMessages as $errorMessage ) echo “<li>$errorMessage </li>”; echo ‘<p>Please <a href=”javascript:history.go(-1)”>go back</a> and try again.</p>’; } else { echo “<p>Thanks for your order! You ordered the following items:</ p><ul>”; $productCodes = preg_split( “/\W+/”, $_POST[“productCodes”], -1, PREG_ SPLIT_NO_EMPTY ); $products = preg_replace_callback( $productCodePattern, “expandProductCodes”, $productCodes ); foreach ( $products as $product ) echo “<li>$product</li>”; echo “</ul>”; } } function expandProductCodes( $matches ) { c18.indd 566c18.indd 566 9/21/09 6:18:02 PM9/21/09 6:18:02 PM Chapter 18: String Matching with Regular Expressions 567 $productCodes = array( “SW” => “SuperWidget”, “MW” => “MegaWidget”, “WW” => “WonderWidget” ); return $productCodes[$matches[1]] . “ model #” . $matches[2]; } ?> </body> </html> Run the script by opening its URL in your Web browser. Fill in the form with your email address and phone number, along with some product codes in the prescribed format, as shown in Figure 18-2. Click Send Order to process the form. Notice how the thank-you page (Figure 18-3) expands the product codes you entered into more meaningful product names. Try returning to the form and entering email addresses and phone numbers in different formats, then resending the form. You should find that, although the script is quite tolerant of different formats, it still rejects any email addresses or phone numbers that don’t obey the standard formatting rules. Figure 18-2 c18.indd 567c18.indd 567 9/21/09 6:18:02 PM9/21/09 6:18:02 PM [...]... well-formed but also valid 581 Part III: Using PHP in Practice Reading XML Documents with PHP Recently, as the XML specification has gained prominence as a means of exchanging and storing data, PHP has added progressively more functions and classes to make it easier to work with XML documents In the remainder of this chapter you concentrate on the following XML features in PHP: ❑ Reading, or parsing,... applications Part III: Using PHP in Practice PHP has many features and functions that make working with XML data fast and efficient, as well as intuitive In this chapter you learn the basics of XML, and how to create XML documents from scratch You then move onto using PHP s XML Parser extension to read and parse XML documents programmatically Once you’ve mastered XML Parser, you explore PHP s DOM extension... specifies the encoding in which character data is passed to your event handler functions By default, the parser sends characters using UTF -8 encoding, but you can change this to either ISO -88 59-1 or US-ASCII if you prefer For example: $parser = xml_parser_create( “US-ASCII” ); 582 Chapter 19: Working with XML Creating Event Handlers Now that you have a parser to work with, you need to create functions to handle... xml_parser .php in your document root folder: Parsing an XML File Parsing an XML File < ?php 585 Part III: Using PHP in... name as a string: xml_set_character_data_handler( $parser, “characterDataHandler” ); 583 Part III: Using PHP in Practice Parsing the XML Document Now you’re ready to actually parse the document First, if the document is a file on disk or at a URL, you need to read its contents into a string variable using, for example, PHP s file_get_contents() function Once you have your XML in a string variable, call... uses PHP s xml_parser_set_option() function to set the XML_OPTION_CASE_FOLDING parser option to false By default, XML Parser converts all the data that it passes to the event handlers to uppercase; in practice this isn’t that useful because XML is case-sensitive, so the script turns this option off: $parser = xml_parser_create(); xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, false ); 588 Chapter... set the encoding of characters that are sent to the event handlers, much like the optional argument that you can pass to xml_parser_create() described earlier See the online PHP manual at http://www .php. net/ manual/en/book.xml .php for more details Next the script uses xml_set_element_handler() and xml_set_character_data_handler() to register the three event handlers created earlier: xml_set_element_handler(... xml_set_default_ handler() that lets you specify an event handler to deal with other parts of an XML document, such as the DOCTYPE line For more details, see http://www .php. net/manual/en/book.xml .php Writing and Manipulating XML Documents with PHP Although XML Parser is a very useful extension, it can only read XML documents; it can’t alter documents or create new documents Furthermore, the event-based parsing... the various nodes (elements, attributes, and so on) of an XML document as a tree of objects If you’ve done any work with the DOM in JavaScript then you’re in luck — the PHP DOM classes work in a very similar way 589 Part III: Using PHP in Practice The DOM is a very flexible way of working Using the DOM extension, you can read in an XML document as a tree of objects, and then traverse this tree at your... nodeType can have many values, and they’re represented by a set of predefined constants Here are a few of the more common ones (you can get a complete list from the online PHP manual at http://www php. net/manual/en/dom.constants .php) : Constant Description XML_ELEMENT_NODE The node is an element, represented as a DOMElement object XML_ATTRIBUTE_NODE The node is an attribute, represented as a DOMAttr . $89 .50 . “ . “The product will be released on Jan 16, 2010.”; $patterns = array( “/\$d+.d{2}/”, “/w {3} d{1,2}, d{4}/” ); c 18. indd 55 8c 18. indd 55 8 9/21/09 6:17 :59 PM9/21/09 6:17 :59 . number, and a list of product codes. c 18. indd 56 8c 18. indd 56 8 9/21/09 6: 18: 03 PM9/21/09 6: 18: 03 PM Chapter 18: String Matching with Regular Expressions 56 9 The expression has been laid out in. ❑ ❑ ❑ c 18. indd 56 3c 18. indd 56 3 9/21/09 6: 18: 01 PM9/21/09 6: 18: 01 PM 56 4 Part III: Using PHP in Practice This code displays: Array ( [0] = > [1] = > hello [2] = > [3] = >

Ngày đăng: 09/08/2014, 14:21

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan