|
Server : Apache/2.4.62 System : FreeBSD fbsdweb2.web.rcn.net 14.1-RELEASE FreeBSD 14.1-RELEASE releng/14.1-n267679-10e31f0946d8 GENERIC amd64 User : www ( 80) PHP Version : 8.3.8 Disable Function : NONE Directory : /domains/irtiweb/CATS/lib/ |
Upload File : |
<?php
/**
* CATS
* String Utility Library
*
* Copyright (C) 2005 - 2007 Cognizo Technologies, Inc.
*
*
* The contents of this file are subject to the CATS Public License
* Version 1.1a (the "License"); you may not use this file except in
* compliance with the License. You may obtain a copy of the License at
* http://www.catsone.com/.
*
* Software distributed under the License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
* License for the specific language governing rights and limitations
* under the License.
*
* The Original Code is "CATS Standard Edition".
*
* The Initial Developer of the Original Code is Cognizo Technologies, Inc.
* Portions created by the Initial Developer are Copyright (C) 2005 - 2007
* (or from the year in which this file was created to the year 2007) by
* Cognizo Technologies, Inc. All Rights Reserved.
*
*
* @package CATS
* @subpackage Library
* @copyright Copyright (C) 2005 - 2007 Cognizo Technologies, Inc.
* @version $Id: StringUtility.php 3587 2007-11-13 03:55:57Z will $
*/
/**
* String Utility Library
* @package CATS
* @subpackage Library
*/
class StringUtility
{
const matchPHSeparator = '[\s\/.-]*'; /* PCRE */
const matchPHCountryCode = '[(]?[+]?\d{0,3}[)]?'; /* PCRE */
const matchPHECountryCode = '[(]?[+]?(?P<countryCode>\d{0,3})[)]?'; /* PCRE */
const matchPHAreaCode = '[(]?[2-9]{1}\d{2}[)]?'; /* PCRE */
const matchPHEAreaCode = '[(]?(?P<areaCode>[2-9]{1}\d{2})[)]?'; /* PCRE */
const matchPHExchange = '\d{3}'; /* PCRE */
const matchPHEExchange = '(?P<exchange>\d{3})'; /* PCRE */
const matchPHNumber = '\d{4}'; /* PCRE */
const matchPHENumber = '(?P<number>\d{4})'; /* PCRE */
const matchPHExtension = '([(]?(?:e?xt?(?:ension|)|#|[*]|)[)]?[\s\/.-]*\d{1,6}[)]?)?'; /* PCRE */
const matchPHEExtension = '([(]?(?:e?xt?(?:ension|)|#|[*]|)[)]?[\s\/.-]*(?P<extension>\d{1,6})[)]?)?'; /* PCRE */
const matchEmailDot = '(?:\.|\s*\(?\[?dot\)?\]?\s*)'; /* PCRE */
const matchEmailAt = '(?:@|\s*\(?\[?at\)?\]?\s*)'; /* PCRE */
const matchEmailTLD = '[a-z]{2,}'; /* PCRE */
const matchEmailETLD = '(?P<tld>[a-z]{2,})'; /* PCRE */
const matchEmailHost = '([a-z0-9_-]+(?:\.|\s*\(?\[?dot\)?\]?\s*)?)+'; /* PCRE */
const matchEmailEHost = '(?P<host>(?:[a-z0-9_-]+(?:\.|\s*\(?\[?dot\)?\]?\s*)?)+)'; /* PCRE */
const matchEmailUser = '[a-z0-9._-]+'; /* PCRE */
const matchEmailEUser = '(?P<user>[a-z0-9._-]+)'; /* PCRE */
const matchURLDomain = '(?:localhost|(?:\d{1,3}\.){3}\d{1,3}|(?:[a-z\d-]+\.)*[a-z\d-]+\.[a-z]{2,6})'; /* PCRE */
const matchEURLDomain = '(?P<domain>localhost|(?:\d{1,3}\.){3}\d{1,3}|(?:[a-z\d-]+\.)*[a-z\d-]+\.[a-z]{2,6})'; /* PCRE */
const matchEURLProtocol = '(?:(?P<protocol>[a-z]+)(?:\:\/\/))?'; /* PCRE */
const matchEURLUserPassword = '(?:(?P<user>[a-z\d.-]+)(?:\:(?P<password>[a-z&%\$\d.-]+))*@)?'; /* PCRE */
const matchEURLPort = '\:?(?P<port>\d+)?'; /* PCRE */
const matchEURLExtras = '(?P<extras>[\/][a-z\d.,\x27?\/+&%\$#=~_@-]*)*'; /* PCRE */
const matchURLProtocol = '(?:[a-z]+\:\/\/|)'; /* PCRE */
const matchURLUserPassword = '(?:[a-z\d.-]+(?:\:[a-z&%\$\d.-]+)*@|)'; /* PCRE */
const matchURLPort = '\:?(\d+)?'; /* PCRE */
const matchURLExtras = '([\/][a-z\d.,\x27?\/+&%\$#=~_@-]*)*'; /* PCRE */
/* Prevent this class from being instantiated. */
private function __construct() {}
private function __clone() {}
/**
* Returns true if the string appears to be a phone number. Leading /
* trailing text is expected to be stripped prior to call.
*
* @param string to test
* @return boolean is most likely a phone number
*/
public static function isPhoneNumber($string)
{
if (preg_match('/^'
. self::matchPHCountryCode . self::matchPHSeparator . self::matchPHAreaCode
. self::matchPHSeparator . self::matchPHExchange . self::matchPHSeparator
. self::matchPHNumber . self::matchPHSeparator . self::matchPHExtension
. '$/i', $string))
{
return true;
}
return false;
}
/**
* Returns true if the string appears to contain a phone number.
*
* @param string to test
* @return boolean most likely contains a phone number
*/
public static function containsPhoneNumber($string)
{
if (preg_match('/'
. self::matchPHCountryCode . self::matchPHSeparator . self::matchPHAreaCode
. self::matchPHSeparator . self::matchPHExchange . self::matchPHSeparator
. self::matchPHNumber . self::matchPHSeparator . self::matchPHExtension
. '/i', $string))
{
return true;
}
return false;
}
/**
* Returns the first phone number that could be extracted from a string.
*
* @param string to test
* @return string phone number or '' if not found
*/
public static function extractPhoneNumber($string)
{
if (preg_match('/'
. self::matchPHECountryCode . self::matchPHSeparator . self::matchPHEAreaCode
. self::matchPHSeparator . self::matchPHEExchange . self::matchPHSeparator
. self::matchPHENumber . self::matchPHSeparator . self::matchPHEExtension
. '/i', $string, $matches))
{
//print_r($matches);
/* Don't format international phone numbers. */
if (!empty($matches['countryCode']) && ($matches['countryCode'] != '1'))
{
return $string;
}
$formattedPhoneNumber = sprintf(
"%s-%s-%s",
$matches['areaCode'],
$matches['exchange'],
$matches['number']
);
if (isset($matches['extension']) && !empty($matches['extension']))
{
$formattedPhoneNumber .= ' x ' . $matches['extension'];
}
return $formattedPhoneNumber;
}
return '';
}
/**
* Returns an array all phone numbers that could be extracted from a
* string. The array is of the following format:
*
* array(
* [0] => array(
* 'formatted' => 'Formatted Phone Number'
* 'unformatted' => 'Phone Number Exactly as Found'
* ),
* [1] => array(
* 'formatted' => 'Formatted Phone Number'
* 'unformatted' => 'Phone Number Exactly as Found'
* ),
* ...
*
* @param string to test
* @return array matches or empty array if not found
*/
public static function extractAllPhoneNumbers($string)
{
$formattedPhoneNumbers = array();
if (preg_match_all('/'
. self::matchPHECountryCode . self::matchPHSeparator . self::matchPHEAreaCode
. self::matchPHSeparator . self::matchPHEExchange . self::matchPHSeparator
. self::matchPHENumber . self::matchPHSeparator . self::matchPHEExtension
. '/i', $string, $matches, PREG_SET_ORDER))
{
//print_r($matches);
foreach ($matches as $matchIndex => $match)
{
$formattedPhoneNumbers[$matchIndex]['unformatted'] = $match[0];
$formattedPhoneNumbers[$matchIndex]['formatted'] = sprintf(
"%s-%s-%s",
$match['areaCode'],
$match['exchange'],
$match['number']
);
if (isset($match['extension']) && !empty($match['extension']))
{
$formattedPhoneNumbers[$matchIndex]['formatted'] .= ' x ' . $match['extension'];
}
}
}
return $formattedPhoneNumbers;
}
/**
* Returns true if the string appears to be an e-mail address. This also
* supports '@' -> 'at', and '.' -> 'dot' anti-spam addresses.
*
* @param string to test
* @return boolean is most likely a phone number
*/
public static function isEmailAddress($string)
{
if (preg_match('/^' . self::matchEmailUser . self::matchEmailAt
. self::matchEmailHost . self::matchEmailDot
. self::matchEmailTLD . '$/i', $string))
{
return true;
}
return false;
}
/**
* Returns true if the string appears to contain an e-mail address. This
* also supports '@' -> 'at', and '.' -> 'dot' anti-spam addresses.
*
* @param string to test
* @return boolean is most likely a phone number
*/
public static function containsEmailAddress($string)
{
if (preg_match('/' . self::matchEmailUser . self::matchEmailAt
. self::matchEmailHost . self::matchEmailDot
. self::matchEmailTLD . '/i', $string))
{
return true;
}
return false;
}
/**
* Returns the first e-mail address that could be extracted from a line.
*
* @param string to test
* @return string e-mail address or '' if none found
*/
public static function extractEmailAddress($string)
{
if (preg_match('/' . self::matchEmailEUser . self::matchEmailAt
. self::matchEmailEHost . self::matchEmailDot
. self::matchEmailETLD . '/i', $string, $matches))
{
$formattedEmailAddress = sprintf(
"%s@%s.%s",
$matches['user'],
$matches['host'],
$matches['tld']
);
$formattedEmailAddress = preg_replace(
'/' . self::matchEmailDot . '/i', '.', $formattedEmailAddress
);
return $formattedEmailAddress;
}
return '';
}
/**
* Returns the given string with any e-mail addresses removed. If $trim is
* true, trim() will be run on the string before return.
*
* @param string to work on
* @param boolean trim the string after extraction?
* @return string without e-mail addresses
*/
public static function removeEmailAddress($string, $trim = false)
{
$string = preg_replace('/' . self::matchEmailUser . self::matchEmailAt
. self::matchEmailHost . self::matchEmailDot
. self::matchEmailTLD . '/i', '', $string);
if ($trim)
{
$string = trim($string);
}
return $string;
}
/**
* Returns true if the string could be a url.
*
* @param string to test
* @return boolean is most likely a URL
*/
public static function isURL($string)
{
if (preg_match('/^' . self::matchURLProtocol .
self::matchURLUserPassword . self::matchURLDomain .
self::matchURLPort . self::matchURLExtras . '$/i',
$string, $matches))
{
return true;
}
return false;
}
/**
* Returns the first URL address that could be extracted from a line.
*
* @param string to test
* @return string URL or '' if none found
*/
public static function extractURL($string)
{
if (preg_match('/^(|.*\s+)' . self::matchEURLProtocol .
self::matchEURLUserPassword . self::matchEURLDomain .
self::matchEURLPort . self::matchEURLExtras .
'/i', $string, $matches))
{
if (!empty($matches['protocol']))
{
$protocol = $matches['protocol'];
}
else
{
$protocol = 'http';
}
if (!empty($matches['user']))
{
if (!empty($matches['password']))
{
$userPassword = $matches['user'] . ':' .
$matches['password'] . '@';
}
else
{
$userPassword = $matches['user'] . '@';
}
}
else
{
$userPassword = '';
}
if (isset($matches['port']) && !empty($matches['port']) &&
$matches['port'] != 80)
{
$port = ':' . $matches['port'];
}
else
{
$port = '';
}
if (isset($matches['extras']) && !empty($matches['extras']))
{
$extras = $matches['extras'];
}
else
{
$extras = '/';
}
$formattedURL = sprintf(
"%s://%s%s%s%s",
$protocol,
$userPassword,
$matches['domain'],
$port,
$extras
);
return $formattedURL;
}
return '';
}
/**
* Checks if a string is a valid IP address.
*
* @param string string to test
* @return boolean is valid IP address
*/
public static function isIPAddress($string)
{
$octet = '(?:\d{1,2}|1\d\d|2[0-4]\d|25[0-5])';
if (preg_match('/^' . $octet . '\.' . $octet . '\.' . $octet . '\.' . $octet . '$/', $string))
{
return true;
}
return false;
}
/**
* Removes all blank lines from a string.
*
* @return string cleaned string
*/
public static function removeEmptyLines($string)
{
$string = preg_replace("/[\r\n]+[\s\t]*[\r\n]+/", "\n", $string);
$string = preg_replace("/^[\s\t]*[\r\n]+/", "", $string);
$string = trim($string);
return $string;
}
/**
* Counts the number of 'words' / tokens in a string delimeted by a
* character in $splitCharacters.
*
* @return int tokens in string
*/
public static function countTokens($splitCharacters, $string)
{
if (!strtok($string, $splitCharacters))
{
return 0;
}
$tokenCount = 1;
while (strtok($splitCharacters))
{
++$tokenCount;
}
return $tokenCount;
}
/**
* Splits a string into an array by 'words' / tokens delimeted by a
* character in $splitCharacters.
*
* @param string delimiter characters used to split the string into tokens
* @param string string to split into tokens
* @return array tokens or an empty array if no tokens are found
*/
public static function tokenize($splitCharacters, $string)
{
$tokenIndex = 0;
$tokens[$tokenIndex] = strtok($string, $splitCharacters);
if ($tokens[$tokenIndex] === false || empty($tokens[$tokenIndex]))
{
return array();
}
while (true)
{
++$tokenIndex;
$tempToken = strtok($splitCharacters);
if ($tempToken === false || empty($tempToken))
{
break;
}
else
{
$tokens[$tokenIndex] = $tempToken;
}
}
return $tokens;
}
/**
* Makes a first name and last name into a first name and last initial
* (with an optional maximum length).
*
* @return formatted first initial and last name.
*/
public static function makeInitialName($firstName, $lastName,
$lastCommaFirst = false, $maxLength = 1000)
{
if (empty($firstName) && empty($lastName))
{
return '';
}
if ($lastCommaFirst)
{
$firstInitial = $firstName{0} . '.';
if (strlen($lastName) > $maxLength)
{
return ucwords(
substr($lastName, 0, $maxLength) . ', ' . $firstInitial
);
}
return ucwords($lastName . ', ' . $firstInitial);
}
$lastInitial = $lastName{0} . '.';
if (strlen($firstName) > $maxLength)
{
return ucwords(
substr($firstName, 0, $maxLength) . ' ' . $lastInitial
);
}
return ucwords($firstName . ' ' . $lastInitial);
}
/**
* Formats a city and state as "City, State" if neither are empty, "State"
* if city is empty, or "City" if state is empty.
*
* @return formatted city and state
*/
public static function makeCityStateString($city, $state)
{
$city = trim($city);
$state = trim($state);
if (!empty($city))
{
$string = $city;
if (!empty($state))
{
$string .= ', ' . $state;
}
return $string;
}
return $state;
}
/**
* Returns the specified string in quoted-printable encoding according to
* RFC 2045 (http://www.faqs.org/rfcs/rfc2045).
*
* Slightly modified from documentation comment on php.net by bendi (at)
* interia (dot) pl (http://us2.php.net/quoted_printable_decode).
*
* @return string encoded string
*/
public static function quotedPrintableEncode($string)
{
$string = preg_replace_callback(
'/[^\x21-\x3C\x3E-\x7E\x09\x20]/',
function($result) {
return sprintf("=%02X", ord($result[0]));
},
$string
);
/* Prevent the splitting of lines from interfering with escaped
* characters.
*/
preg_match_all('/.{1,73}([^=]{0,3})?/', $string, $matches);
return implode("=\r\n", $matches[0]);
}
/**
* Returns the specified string with any single-quotes (') escaped (\').
*
* @param string unescaped string
* @return string escaped string
*/
public static function escapeSingleQuotes($string)
{
return str_replace("'", "\'", $string);
}
/* Converts a single CSV line to an array. Note that this cannot handle
* escaped double-quotes inside double quotes (FIXME).
*/
//FIXME: Document me.
public static function CSVLineToArray($string)
{
$string .= '';
$string = trim($string);
if (empty($string))
{
return array();
}
$results = preg_split(
'/,(?=(?:[^"]*"[^"]*")*(?![^"]*"))/',
trim($string)
);
return preg_replace('/^"(.*)"$/', '\1', $results);
}
/* Implemented like JS substring function. */
public static function JSSubString($string, $start, $end)
{
return substr($string, $start, ($end - $start));
}
/**
* Functions like str_replace() except only the first occurrance of
* $needle will be replaced. Array parameters are not supported.
*
* @param string needle
* @param string replacement string
* @param string haystack
* @return string replaced string
*/
public static function replaceOnce($needle, $replace, $haystack)
{
$potision = strpos($haystack, $needle);
if ($potision === false)
{
return $haystack;
}
return substr_replace($haystack, $replace, $potision, strlen($needle));
}
public static function cardinal($x)
{
if ($x <= 0) return 'zero';
$y = ($x % 20);
if ($x >= 10000000) return number_format(strval($x),0);
if (($y=floor($x/1000000)) > 0 && $y <= 9)
{
$val = '';
$z = $x - ($y*1000000);
if ($z > 0) $val = ' ' . StringUtility::cardinal($z);
return StringUtility::cardinal($y) . ' million' . $val;
}
if (($y=floor($x/1000)) > 0 && $y <= 999)
{
$val = '';
$z = $x - ($y*1000);
if ($z > 0) $val = ' ' . StringUtility::cardinal($z);
return StringUtility::cardinal($y) . ' thousand' . $val;
}
if (($y=floor($x/100)) > 0 && $y <= 9)
{
$val = '';
$z = $x - ($y*100);
if ($z > 0) $val = ' and ' . StringUtility::cardinal($z);
return StringUtility::cardinal($y) . ' hundred' . $val;
}
switch($y=floor($x/10))
{
case 2:
$val = 'twenty';
if (($z = $x % ($y*10)) > 0 && $z <= 9) $val .= ' ' . StringUtility::cardinal($z);
return $val;
case 3:
$val = 'thirty';
if (($z = $x % ($y*10)) > 0 && $z <= 9) $val .= ' ' . StringUtility::cardinal($z);
return $val;
case 4:
$val = 'fourty';
if (($z = $x % ($y*10)) > 0 && $z <= 9) $val .= ' ' . StringUtility::cardinal($z);
return $val;
case 5:
$val = 'fifty';
if (($z = $x % ($y*10)) > 0 && $z <= 9) $val .= ' ' . StringUtility::cardinal($z);
return $val;
case 6:
$val = 'sixty';
if (($z = $x % ($y*10)) > 0 && $z <= 9) $val .= ' ' . StringUtility::cardinal($z);
return $val;
case 7:
$val = 'seventy';
if (($z = $x % ($y*10)) > 0 && $z <= 9) $val .= ' ' . StringUtility::cardinal($z);
return $val;
case 8:
$val = 'eighty';
if (($z = $x % ($y*10)) > 0 && $z <= 9) $val .= ' ' . StringUtility::cardinal($z);
return $val;
case 9:
$val = 'ninety';
if (($z = $x % ($y*10)) > 0 && $z <= 9) $val .= ' ' . StringUtility::cardinal($z);
return $val;
}
switch($x)
{
case 1: return 'one';
case 2: return 'two';
case 3: return 'three';
case 4: return 'four';
case 5: return 'five';
case 6: return 'six';
case 7: return 'seven';
case 8: return 'eight';
case 9: return 'nine';
case 10: return 'ten';
case 11: return 'eleven';
case 12: return 'twelve';
case 13: return 'thirteen';
case 14: return 'fourteen';
case 15: return 'fifteen';
case 16: return 'sixteen';
case 17: return 'seventeen';
case 18: return 'eighteen';
case 19: return 'nineteen';
}
}
}
?>