Skip to content

Commit

Permalink
* 1.16 New methods Text::wildcardComparison() and Text::endsWith()
Browse files Browse the repository at this point in the history
  • Loading branch information
jorgecc committed Jun 6, 2020
1 parent b23f6d5 commit 6ff9bda
Show file tree
Hide file tree
Showing 4 changed files with 175 additions and 39 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ Text::addParenthesis('(hello)');

## Version list

* 1.16 New methods Text::wildcardComparison() and Text::endsWith()
* 1.15 New method Text::parseArg2()
* 1.14 Text::camelCase() solved a small bug
* 1.13 Text::replaceCurlyVariable() updated
* 1.12
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "eftec/mapache-commons",
"description": "It's a set of useful functions for PHP. The name is a pun.",
"version": "1.14",
"version": "1.16",
"type": "library",
"keywords": [
"collection",
Expand Down
195 changes: 157 additions & 38 deletions lib/Text.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,13 @@
* Class Text
*
* @package mapache_commons
* @version 1.14 2020-feb-12
* @version 1.16 2020-06-06
* @copyright Jorge Castro Castillo
* @license Apache-2.0
* @see https://github.com/EFTEC/mapache-commons
*/
class Text {
class Text
{

/**
* Returns true if the str is (completelly) uppercase
Expand Down Expand Up @@ -105,13 +106,13 @@ public static function removeParenthesis($txt, $start = '(', $end = ')') {
return false;
}
foreach ($start as $k => $v) {
if (substr($txt, 0, 1) === $v && substr($txt, -1) === $end[$k]) {
return substr($txt, 1, strlen($txt) - 2);
if ($txt[0] === $v && substr($txt, -1) === $end[$k]) {
return substr($txt, 1, -1);
}
}
} else {
if (substr($txt, 0, 1) === $start && substr($txt, -1) === $end) {
return substr($txt, 1, strlen($txt) - 2);
if ($txt[0] === $start && substr($txt, -1) === $end) {
return substr($txt, 1, -1);
}
}
return $txt;
Expand Down Expand Up @@ -152,19 +153,18 @@ public static function replaceBetween(
$offset = $ini + $len;
return substr_replace($haystack, $replaceText, $ini, $len);

} else {
$ini += strlen($startNeedle);
$len = $p1 - $ini;
$offset = $ini + $len;
return substr_replace($haystack, $replaceText, $ini, $len);
}

$ini += strlen($startNeedle);
$len = $p1 - $ini;
$offset = $ini + $len;
return substr_replace($haystack, $replaceText, $ini, $len);
}

/**
* Remove the first character(s) for a string
*
* @param string $str The input text
* @param string $str The input text
* @param int $length The amount of characters to remove
*
* @return bool|string
Expand All @@ -176,7 +176,7 @@ public static function removeFirstChars($str, $length = 1) {
/**
* Remove the last character(s) for a string
*
* @param string $str The input text
* @param string $str The input text
* @param int $length The amount of characters to remove
*
* @return bool|string
Expand Down Expand Up @@ -215,14 +215,14 @@ public static function getArgument($str, $set = '=', $trimValue = true) {
/**
* It returns the first non-space position inside a string.
*
* @param string $str input string
* @param int $offset offset position
* @param string $str input string
* @param int $offset offset position
* @param string $charlist list of characters considered as space
*
* @return int the position of the first non-space
*/
public static function strPosNotSpace($str, $offset = 0, $charlist=" \t\n\r\0\x0B") {
$txtTmp = substr($str, 0, $offset) . ltrim(substr($str, $offset),$charlist);
public static function strPosNotSpace($str, $offset = 0, $charlist = " \t\n\r\0\x0B") {
$txtTmp = substr($str, 0, $offset) . ltrim(substr($str, $offset), $charlist);
return strlen($str) - strlen($txtTmp) + $offset;
}

Expand Down Expand Up @@ -259,6 +259,7 @@ public static function strposArray($haystack, $needles, $offset = 0, $last = fal
/**
* It transforms a text = 'a1=1,a2=2' into an associative array<br/>
* It uses the method parse_str() to do the conversion<br/>
* <b>Note:<b> It doesn't work with quotes or double quotes. a1="aa,bb",bb=30 doesn't work
*
* @param string $text The input string with the initial values
* @param string $separator The separator
Expand All @@ -268,7 +269,7 @@ public static function strposArray($haystack, $needles, $offset = 0, $last = fal
public static function parseArg($text, $separator = ',') {
$tmpToken = '¶|¶';
$output = [];
if ($separator == '&') {
if ($separator === '&') {
parse_str($text, $output);
return $output;
}
Expand All @@ -280,6 +281,54 @@ public static function parseArg($text, $separator = ',') {
return $output;
}

/**
* It's the same than parseArg() but it's x3 times slower.<br>
* It also considers quotes and doubles quotes.<br>
* Example:
* <pre>
* Text::parseArg2("a1=1,a2=2,a3="aa,bb"); // ["a1"=>1,"a2"=>2,"a3"=>""aa,bb""]
* Text::parseArg("a1=1,a2=2,a3="aa,bb"); // ["a1"=>1,"a2"=>2,"a3"=>""aa","bb""=>""]
* </pre>
*
* @param string $text The input string with the initial values
* @param string $separator The separator. It does not separates text inside quotes or double-quotes.
*
* @return array An associative array
*/
public static function parseArg2($text, $separator = ',') {

$chars = str_split($text);
$parts = [];
$nextpart = "";
$strL = count($chars);
for ($i = 0; $i < $strL; $i++) {
$char = $chars[$i];
if ($char === '"' || $char === "'") {
$inext = strpos($text, $char, $i + 1);
$inext = $inext === false ? $strL : $inext;
$nextpart .= substr($text, $i, $inext - $i + 1);
$i = $inext;
} else {
$nextpart .= $char;
}
if ($char === $separator) {
$parts[] = substr($nextpart, 0, -1);
$nextpart = "";
}
}
if (strlen($nextpart) > 0) {
$parts[] = $nextpart;
}
$result = [];
foreach ($parts as $part) {
$r = explode('=', $part, 2);
if (count($r) == 2) {
$result[trim($r[0])] = trim($r[1]);
}
}
return $result;
}

/**
* It parses a natural string and returns a declarative array<br>
* Example: natural("v1 obj obj1 type type1"<br>
Expand Down Expand Up @@ -321,38 +370,109 @@ public static function naturalArg($txt, $separators) {
}
// validation
foreach ($result as $k => $item) {
if ($separators[$k] == 'req' && $result[$k] === null) {
if ($separators[$k] === 'req' && $result[$k] === null) {
// it misses one required value.
return null;
}
}
return $result;
}

/**
* It compares with wildcards (*) and returns true if both strings are equals<br>
* The wildcards only works at the beginning or at the end of the string.<br>
* <b>Example:<b><br>
* <pre>
* Text::wildCardComparison('abcdef','abc*'); // true
* Text::wildCardComparison('abcdef','*def'); // true
* Text::wildCardComparison('abcdef','*abc*'); // true
* Text::wildCardComparison('abcdef','*cde*'); // true
* Text::wildCardComparison('abcdef','*cde'); // false
*
* </pre>
*
* @param string $text
* @param string|null $textWithWildcard
*
* @return bool
*/
public static function wildCardComparison($text,$textWithWildcard) {
if(($textWithWildcard===null && $textWithWildcard==='')
|| $textWithWildcard==='**'
|| strpos($textWithWildcard,'*')===false) {
// if the text with wildcard is null or empty or it contains two ** or it contains no * then..
return $text==$textWithWildcard;
}
$c0=$textWithWildcard[0];
$c1=substr($textWithWildcard, -1);
$textWithWildcardClean=str_replace('*','',$textWithWildcard);
$p0=strpos($text,$textWithWildcardClean);
if($p0===false) {
// no matches.
return false;
}
if($c0==='*' && $c1==='*') {
// $textWithWildcard='*asasasas*'
return true;
}
if($c1==='*') {
// $textWithWildcard='asasasas*'
return $p0===0;
}
// $textWithWildcard='*asasasas'
return static::endsWith($text,$textWithWildcardClean);

}

/**
* it returns true if $string ends with $endString<br>
* <b>Example:<b><br>
* <pre>
* Text::endsWidth('hello world','world'); // true
* </pre>
*
* @param $string
* @param $endString
*
* @return bool
*/
public static function endsWith($string, $endString)
{
$len = strlen($endString);
if ($len == 0) {
return true;
}
return (substr($string, -$len) === $endString);
}

/**
* Replaces all variables defined between {{ }} by a variable inside the dictionary of values.<br>
* Example:<br>
* replaceCurlyVariable('hello={{var}}',['var'=>'world']) // hello=world<br>
* replaceCurlyVariable('hello={{var}}',['varx'=>'world']) // hello=<br>
* replaceCurlyVariable('hello={{var}}',['varx'=>'world'],true) // hello={{var}}<br>
*
* @param string $string The input value. It could contains variables defined as {{namevar}}
* @param array $values The dictionary of values.
* @param bool $notFoundThenKeep [false] If true and the value is not found, then it keeps the value.
* Otherwise, it is replaced by an empty value
* @param string $string The input value. It could contains variables defined as {{namevar}}
* @param array $values The dictionary of values.
* @param bool $notFoundThenKeep [false] If true and the value is not found, then it keeps the value.
* Otherwise, it is replaced by an empty value
*
* @return string|string[]|null
*/
public static function replaceCurlyVariable($string,$values,$notFoundThenKeep=false) {
if(strpos($string,'{{')===false) return $string; // nothing to replace.
return preg_replace_callback('/{{\s?(\w+)\s?}}/u', function ($matches) use ($values,$notFoundThenKeep) {
public static function replaceCurlyVariable($string, $values, $notFoundThenKeep = false) {
if (strpos($string, '{{') === false) {
return $string;
} // nothing to replace.
return preg_replace_callback('/{{\s?(\w+)\s?}}/u', function ($matches) use ($values, $notFoundThenKeep) {
if (is_array($matches)) {
$item = substr($matches[0], 2, strlen($matches[0]) - 4); // removes {{ and }}
return isset($values[$item])? $values[$item] : ($notFoundThenKeep?$matches[0]:'') ;
} else {
$item = substr($matches, 2, strlen($matches) - 4); // removes {{ and }}
return isset($values[$item])? $values[$item] : ($notFoundThenKeep?$matches:'') ;
$item = substr($matches[0], 2, -2); // removes {{ and }}
/** @noinspection NullCoalescingOperatorCanBeUsedInspection */
return isset($values[$item]) ? $values[$item] : ($notFoundThenKeep ? $matches[0] : '');
}

$item = substr($matches, 2, -2); // removes {{ and }}
/** @noinspection NullCoalescingOperatorCanBeUsedInspection */
return isset($values[$item]) ? $values[$item] : ($notFoundThenKeep ? $matches : '');
}, $string);
}

Expand Down Expand Up @@ -390,12 +510,12 @@ public static function hasParenthesis($txt, $start = '(', $end = ')') {
return false;
}
foreach ($start as $k => $v) {
if (substr($txt, 0, 1) === $v && substr($txt, -1) === $end[$k]) {
if ($txt[0] === $v && substr($txt, -1) === $end[$k]) {
return true;
}
}
} else {
if (substr($txt, 0, 1) === $start && substr($txt, -1) === $end) {
if ($txt[0] === $start && substr($txt, -1) === $end) {
return true;
}
}
Expand All @@ -422,8 +542,8 @@ public static function camelCase($txt) {
$l = strlen($txt);
for ($i = 0; $i < $l; $i++) {
$c = $txt[$i];
if ($c == '_' || $c == ' ') {
if($i!=$l-1) {
if ($c === '_' || $c === ' ') {
if ($i != $l - 1) {
$result .= strtoupper($txt[$i + 1]);
$i++;
} else {
Expand All @@ -434,10 +554,9 @@ public static function camelCase($txt) {
}
}
return $result;
} else {
// the text is simple.
return strtolower(substr($txt, 0, 1)) . substr($txt, 1);
}

// the text is simple.
return strtolower($txt[0]) . substr($txt, 1);
}
}
15 changes: 15 additions & 0 deletions test/TextTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ public function teststrPosNotSpace() {
$this->assertEquals(2,Text::strPosNotSpace(" \nabc"));
$this->assertEquals(1,Text::strPosNotSpace(" \nabc",0," "));
}
public function testWildCard() {
$this->assertEquals(true,Text::wildCardComparison('abcdef','abc*'));
$this->assertEquals(true,Text::wildCardComparison('abcdef','*def'));
$this->assertEquals(true,Text::wildCardComparison('abcdef','*abc*'));
$this->assertEquals(false,Text::wildCardComparison('abcdef','1abc*'));
$this->assertEquals(false,Text::wildCardComparison('abcdef','*1def'));
$this->assertEquals(false,Text::wildCardComparison('abcdef','*1abc*'));
}
public function testReplaceBetween()
{
$this->assertEquals("Hello Wayne World",Text::replaceBetween('Hello Brave World','Hello','World',' Wayne '));
Expand All @@ -88,6 +96,13 @@ public function testReplaceBetween()
public function testparseArg() {
$this->assertEquals(['a'=>'1','b'=>'2'],Text::parseArg('a=1,b=2'));
$this->assertEquals(['a'=>'1','b'=>'2'],Text::parseArg('a=1&b=2','&'));
$txt="a1=1,a2=2,a3='a1,bb'";
$this->assertEquals([
'a1'=>'1'
,'a2'=>'2'
,'a3'=>"'a1"
,"bb'"=>''],Text::parseArg($txt));
$this->assertEquals(['a1'=>'1','a2'=>'2','a3'=>"'a1,bb'"],Text::parseArg2($txt));
}
public function testReplaceCurlyVariable() {
$this->assertEquals('hello=world',Text::replaceCurlyVariable('hello={{var}}',['var'=>'world']));
Expand Down

0 comments on commit 6ff9bda

Please sign in to comment.