Solved

Preg_match needs to search for a word, not any part of a word that matches

Posted on 2011-09-11
11
319 Views
Last Modified: 2012-05-12
Hi,
Back at the trough of knowledge again...

I'm using preg_match to detect if someone text messages the word 'add' or 'subscribe' in a text message so I know if they want to be subscribed to my app.

if ((preg_match("/add/i", $body)) || (preg_match("/subscribe/i", $body))) {

Open in new window



Problem I've just noticed is I also use:

else if ((preg_match("/remove/i", $body)) || (preg_match("/unsubscribe/i", $body))) {

Open in new window


to tell if they want to be removed. Preg_match is matching any string that contains those letters (case insensitive). Works great for 'add' and 'remove' but 'subscribe' and 'unsubscribe' is a problem. I'm guessing its seeing the 'subscribe' in unsubscribe first and acts accordingly.

What would I use to look for the words? I thought about a space at each end but someone could type out one of the words starting without a space or ending without.
0
Comment
Question by:tjyoung
  • 4
  • 3
  • 2
  • +2
11 Comments
 
LVL 10

Expert Comment

by:Derokorian
Comment Utility
if ((preg_match("/add/i", $body)) || (preg_match("/[^un]subscribe/i", $body))) {

try that. The carat ^ means not matching.
0
 
LVL 10

Expert Comment

by:Derokorian
Comment Utility
Actually it might need to be parentheses instead of brackets.

if ((preg_match("/add/i", $body)) || (preg_match("/(^un)subscribe/i", $body))) {
0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
I believe that you can use the \w character class to delimit words.

you might also find the (XXX) group operator to be useful.
0
 
LVL 1

Author Comment

by:tjyoung
Comment Utility
I don't think the carat method is doing it. Add and Remove are working as expected so I am guessing the other 2 are problems.
0
 
LVL 108

Accepted Solution

by:
Ray Paseur earned 167 total points
Comment Utility
Sorry - not \w, but \b does the word-boundary identification.
http://www.laprbass.com/RAY_temp_tjyoung.php
outputs:
This is a request to add or subscribe MATCHES #(\bADD\b|\bSUBSCRIBE\b)#i
This is a request to unsubscribe or addle
SuBscrIBE MATCHES #(\bADD\b|\bSUBSCRIBE\b)#i
Add. MATCHES #(\bADD\b|\bSUBSCRIBE\b)#i
  Add.??! MATCHES #(\bADD\b|\bSUBSCRIBE\b)#i
AddSubscribe
Subscriber
unsubscribe
un-subscribe MATCHES #(\bADD\b|\bSUBSCRIBE\b)#i

Best regards, ~Ray
<?php // RAY_temp_tjyoung.php
error_reporting(E_ALL);
echo "<pre>";

// TEST STRINGS IN AN ARRAY
$arr = array
( 'This is a request to add or subscribe'
, 'This is a request to unsubscribe or addle'
, 'SuBscrIBE'
, 'Add.'
, '  Add.??!'
, 'AddSubscribe'
, 'Subscriber'
, 'unsubscribe'
, 'un-subscribe'
)
;

// A REGEX TO FIND THE ADD OR SUBSCRIBE
$rgx
= '#'                       // REGEX DELIMITER
. '(\bADD\b|\bSUBSCRIBE\b)' // WORD-DELIMITED "ADD" OR "SUBSCRIBE"
. '#'                       // REGEX DELIMITER
. 'i'                       // CASE-INSENSITIVE
;

foreach ($arr as $str)
{
    echo PHP_EOL . $str;
    if (preg_match($rgx, $str)) echo " MATCHES $rgx";
}

Open in new window

0
Complete VMware vSphere® ESX(i) & Hyper-V Backup

Capture your entire system, including the host, with patented disk imaging integrated with VMware VADP / Microsoft VSS and RCT. RTOs is as low as 15 seconds with Acronis Active Restore™. You can enjoy unlimited P2V/V2V migrations from any source (even from a different hypervisor)

 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Here is another variant.  Note the ambiguity of un-subscribe.  Might require some tinkering!

Outputs:
This is a request to add or subscribe WANTS TO ADD / SUBSCRIBE
This is a request to unsubscribe or addle WANTS TO REMOVE / UNSUB
SuBscrIBE WANTS TO ADD / SUBSCRIBE
Add. WANTS TO ADD / SUBSCRIBE
  Add.??! WANTS TO ADD / SUBSCRIBE
AddSubscribe
Subscriber
unsubscribe WANTS TO REMOVE / UNSUB
un-subscribe WANTS TO ADD / SUBSCRIBE  WANTS TO REMOVE / UNSUB
Please remove me from the list WANTS TO REMOVE / UNSUB
<?php // RAY_temp_tjyoung.php
error_reporting(E_ALL);
echo "<pre>";

// TEST STRINGS IN AN ARRAY
$arr = array
( 'This is a request to add or subscribe'
, 'This is a request to unsubscribe or addle'
, 'SuBscrIBE'
, 'Add.'
, '  Add.??!'
, 'AddSubscribe'
, 'Subscriber'
, 'unsubscribe'
, 'un-subscribe'
, 'Please remove me from the list'
)
;

// A REGEX TO FIND THE ADD OR SUBSCRIBE
$rgx_add
= '#'                           // REGEX DELIMITER
. '(\bADD\b|\bSUBSCRIBE\b)'     // WORD-DELIMITED "ADD" OR "SUBSCRIBE"
. '#'                           // REGEX DELIMITER
. 'i'                           // CASE-INSENSITIVE
;

// A REGEX TO FIND THE REMOVE OR UNSUB-SCRIBE
$rgx_rmv
= '#'                           // REGEX DELIMITER
. '(\bREMOVE\b|\bUN.*?SUBS*?)' // WORD-DELIMITED "REMOVE" OR VARIANT OF "UN-SUBSCRIBE"
. '#'                           // REGEX DELIMITER
. 'i'                           // CASE-INSENSITIVE
;

foreach ($arr as $str)
{
    echo PHP_EOL . $str;
    if (preg_match($rgx_add, $str)) echo " WANTS TO ADD / SUBSCRIBE ";
    if (preg_match($rgx_rmv, $str)) echo " WANTS TO REMOVE / UNSUB ";
}

Open in new window

0
 
LVL 1

Author Comment

by:tjyoung
Comment Utility
Hi Ray,
I'm sure its right in principle but with my limited skillset, I can't seem to implement it into what I'm doing. I've embedded a sample out of desperation after many attempts.

This is the basic idea (I've omitted the db portions etc.)

 
<?php

$From = $_REQUEST['From'];
$body = $_REQUEST['Body'];

header("content-type: text/xml");
echo  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
?>

<Response>

<?php

include '../config.php';

	
if ((preg_match("/add/i", $body)) || (preg_match("/subscribe/i", $body))) {
	

}


 else if ((preg_match("/remove/i", $body)) || (preg_match("/unsubscribe/i", $body))) {

	


} else {?>
		<Sms>We're sorry. Our system did not understand your message. Please contact our station if you have any questions or concerns. Thank you.</Sms>
	<?php } ?>
	
</Response>

Open in new window

0
 
LVL 108

Expert Comment

by:Ray Paseur
Comment Utility
Click here and look at the output.
http://www.laprbass.com/RAY_temp_tjyoung.php

You might want to copy the script at ID:36519788 and adapt it to use your test data instead of my test data.
0
 
LVL 82

Assisted Solution

by:hielo
hielo earned 166 total points
Comment Utility
try:
<?php

$From = $_REQUEST['From'];
$body = $_REQUEST['Body'];

header("content-type: text/xml");
echo  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
?>

<Response>

<?php

include '../config.php';

$temp=str_replace('-','',strtolower($body));	
if ( preg_match('/\b(remove|unsubscribe)\b/', $temp) ) {

	

}
elseif ( preg_match('/(add|subscribe)/', $temp) ) {

	


} else {?>
		<Sms>We're sorry. Our system did not understand your message. Please contact our station if you have any questions or concerns. Thank you.</Sms>
	<?php } ?>
	
</Response>

Open in new window

0
 
LVL 1

Author Comment

by:tjyoung
Comment Utility
Hi heilo,
add, subscribe and remove work but when you send unsubscribe, it thinks it is 'subscribe'.
0
 
LVL 35

Assisted Solution

by:Terry Woods
Terry Woods earned 167 total points
Comment Utility
Ray's idea of using word boundaries should do the trick (have altered hielo's code):
<?php

$From = $_REQUEST['From'];
$body = $_REQUEST['Body'];

header("content-type: text/xml");
echo  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
?>

<Response>

<?php

include '../config.php';

$temp=str_replace('-','',strtolower($body));	
if ( preg_match('/\b(remove|unsubscribe)\b/', $temp) ) {

	

}
elseif ( preg_match('/\b(add|subscribe)\b/', $temp) ) {  # CHANGED THIS LINE

	


} else {?>
		<Sms>We're sorry. Our system did not understand your message. Please contact our station if you have any questions or concerns. Thank you.</Sms>
	<?php } ?>
	
</Response>

Open in new window

0

Featured Post

Backup Your Microsoft Windows Server®

Backup all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Join & Write a Comment

Popularity Can Be Measured Sometimes we deal with questions of popularity, and we need a way to collect opinions from our clients.  This article shows a simple teaching example of how we might elect a favorite color by letting our clients vote for …
Part of the Global Positioning System A geocode (https://developers.google.com/maps/documentation/geocoding/) is the major subset of a GPS coordinate (http://en.wikipedia.org/wiki/Global_Positioning_System), the other parts being the altitude and t…
The viewer will learn how to look for a specific file type in a local or remote server directory using PHP.
The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now