From d51b37d267edbd8b444dae0b899ed3f3946717ad Mon Sep 17 00:00:00 2001 From: Inhere Date: Sun, 7 Nov 2021 04:15:22 +0800 Subject: [PATCH] enhance: update some string util commands logic --- app/Concern/StaticPathAliasTrait.php | 19 +++- app/Console/Controller/StringController.php | 86 ++++++++++++++----- app/Helper/KiteUtil.php | 15 ++++ resource/mandocs/zh-CN/regex.md | 39 ++++++++- resource/packages.md | 7 +- .../templates/gen-by-parse/gen-go-funcs.tpl | 2 +- 6 files changed, 139 insertions(+), 29 deletions(-) diff --git a/app/Concern/StaticPathAliasTrait.php b/app/Concern/StaticPathAliasTrait.php index 0cd165f..3ab8702 100644 --- a/app/Concern/StaticPathAliasTrait.php +++ b/app/Concern/StaticPathAliasTrait.php @@ -21,9 +21,24 @@ trait StaticPathAliasTrait * get real value by alias * * @param string $alias + * @param bool $throwEx + * * @return string */ public static function alias(string $alias, bool $throwEx = false): string + { + return self::resolve($alias, $throwEx); + } + + /** + * resolve path alias to real value + * + * @param string $alias + * @param bool $throwEx + * + * @return string + */ + public static function resolve(string $alias, bool $throwEx = false): string { // Not an alias if (!$alias || $alias[0] !== '@') { @@ -66,7 +81,7 @@ public static function hasAlias(string $name): bool */ public static function setAlias(string $alias, string $value): void { - self::$aliases[$alias] = self::alias($value); + self::$aliases[$alias] = self::resolve($value); } /** @@ -81,7 +96,7 @@ public static function setAliases(array $aliases): void continue; } - self::$aliases[$alias] = self::alias($realPath); + self::$aliases[$alias] = self::resolve($realPath); } } diff --git a/app/Console/Controller/StringController.php b/app/Console/Controller/StringController.php index ff9dcff..cd0fb0e 100644 --- a/app/Console/Controller/StringController.php +++ b/app/Console/Controller/StringController.php @@ -14,6 +14,7 @@ use Inhere\Kite\Console\Component\Clipboard; use Inhere\Kite\Console\Component\ContentsAutoReader; use Inhere\Kite\Helper\AppHelper; +use Inhere\Kite\Helper\KiteUtil; use Inhere\Kite\Kite; use Inhere\Kite\Lib\Stream\StringsStream; use InvalidArgumentException; @@ -130,20 +131,14 @@ public function loadCommand(FlagsParser $fs, Output $output): void * -s, --sep The join separator char. Defaults to an empty string. * * @param FlagsParser $fs - * @param Output $output */ - public function joinCommand(FlagsParser $fs, Output $output): void + public function joinCommand(FlagsParser $fs): void { $text = trim($fs->getArg('text')); $text = AppHelper::tryReadContents($text, [ 'loadedFile' => $this->dumpfile, ]); - if (!$text) { - $output->warning('empty input contents for handle'); - return; - } - $lines = explode("\n", $text); $sep = $fs->getOpt('sep'); @@ -162,29 +157,78 @@ public function joinCommand(FlagsParser $fs, Output $output): void * input '@FILEPATH' - will read from the filepath * * @options - * -s, --sep The separator char. defaults is an space string. + * -s, --sep The separator char. defaults is an SPACE. + * --join-sep The sep char for join all items for output. defaults: NL + * -f, --filter array;apply there filters for each substr. + * allow: + * - wrap eg `wrap:'` wrap char(') for each item * * @param FlagsParser $fs - * @param Output $output + * + * @example + * + * {binWithCmd} --sep ',' --join-sep ',' -f "wrap:' " 'tom,john' # Output: 'tom', 'john' */ - public function splitCommand(FlagsParser $fs, Output $output): void + public function splitCommand(FlagsParser $fs): void { $text = trim($fs->getArg('text')); $text = ContentsAutoReader::readFrom($text); - if (!$text) { - $output->warning('empty input contents for handle'); - return; + $sep = $fs->getOpt('sep', ' '); + $sep = KiteUtil::resolveSep($sep); + + $items = explode($sep, $text); + if ($filters = $fs->getOpt('filter')) { + foreach ($items as &$item) { + $item = $this->applyFilters($item, $filters); + } + unset($item); } - $sep = $fs->getOpt('sep', ' '); + $joinSep = $fs->getOpt('join-sep', "\n"); + echo implode(KiteUtil::resolveSep($joinSep), $items), "\n"; + } - $lines = explode($sep, $text); - echo implode("\n", $lines), "\n"; + /** + * apply some simple built in string filters + * + * @param string $str + * @param array $filters + * + * @return string + */ + protected function applyFilters(string $str, array $filters): string + { + foreach ($filters as $filter) { + $args = []; + $argStr = ''; + + // eg 'wrap:,' + if (str_contains($filter, ':')) { + [$filter, $argStr] = explode(':', $filter, 2); + if (strlen($argStr) > 1 && str_contains($argStr, ',')) { + $args = Str::toTypedList($argStr); + } else { + $args = [$argStr]; + } + } + + if ($filter === 'wrap') { + $str = Str::wrap($str, ...$args); + } elseif ($filter === 'append') { + $str .= $argStr; + } elseif ($filter === 'prepend') { + $str = $argStr . $str; + } else { + throw new InvalidArgumentException("unsupported filter: $filter"); + } + } + + return $str; } /** - * Split text to multi line + * Replace all occurrences of the search string with the replacement string * * @arguments * text The source text for handle. @@ -205,10 +249,6 @@ public function replaceCommand(FlagsParser $fs, Output $output): void { $text = trim($fs->getArg('text')); $text = ContentsAutoReader::readFrom($text); - if (!$text) { - $output->warning('empty input contents for handle'); - return; - } $from = $fs->getOpt('from'); $to = $fs->getOpt('to'); @@ -236,6 +276,7 @@ public function replaceCommand(FlagsParser $fs, Output $output): void * -e, --exclude array;exclude line on contains keywords. * -m, --match array;include line on contains keywords. * -t, --trim bool;trim the each line text. + * --each bool;Operate on each substr after split. * --wrap wrap the each line by the separator * -j, --join join the each line by the separator * -c, --cut cut each line by the separator. cut position: L R, eg: 'L=' @@ -305,6 +346,9 @@ public function processCommand(FlagsParser $fs, Output $output): void return Str::has($line, $in); }, count($in) > 0) ->eachIf(function (string $line) use ($replaces) { // replace + // TODO + // $this->applyFilters($line, $filters); + $froms = $tos = []; foreach ($replaces as $replace) { [$from, $to] = explode('/', $replace, 2); diff --git a/app/Helper/KiteUtil.php b/app/Helper/KiteUtil.php index f69cb60..9ee30a4 100644 --- a/app/Helper/KiteUtil.php +++ b/app/Helper/KiteUtil.php @@ -9,12 +9,17 @@ use function dirname; use function in_array; use function is_file; +use function str_replace; /** * class KiteUtil */ class KiteUtil { + + public const NL_CHAR = 'NL'; + public const SPACE_CHAR = 'SPACE'; + public const STDIN_ALIAS = [ '@i', '@stdin', @@ -35,6 +40,16 @@ class KiteUtil 'clipboard', ]; + /** + * @param string $sep + * + * @return string + */ + public static function resolveSep(string $sep): string + { + return str_replace([self::NL_CHAR, self::SPACE_CHAR], ["\n", ' '], $sep); + } + /** * @param string $str * diff --git a/resource/mandocs/zh-CN/regex.md b/resource/mandocs/zh-CN/regex.md index 3447249..21fe8b7 100644 --- a/resource/mandocs/zh-CN/regex.md +++ b/resource/mandocs/zh-CN/regex.md @@ -1,7 +1,6 @@ # 正则表达式 -from: [php.net PCRE 正则语法](https://www.php.net/manual/zh/regexp.reference.meta.php) - +来自于 [php.net PCRE 正则语法](https://www.php.net/manual/zh/regexp.reference.meta.php) ## 元字符 @@ -44,6 +43,7 @@ from: [php.net PCRE 正则语法](https://www.php.net/manual/zh/regexp.reference **用来描述特定的字符类** + 字符 | 含义 -----|----- `\d` | 任意十进制数字 @@ -78,8 +78,41 @@ from: [php.net PCRE 正则语法](https://www.php.net/manual/zh/regexp.reference 单字符量词 | 含义 ------|------ -`*` | 等价于 {0,} +`*` | 等价于 {0,} `+` | 等价于 {1,} `?` | 等价于 {0,1} from: [php.net PCRE 正则语法](https://www.php.net/manual/zh/regexp.reference.repetition.php) + +## 模式修饰符 + +下面列出了当前可用的 PCRE 修饰符。括号中提到的名字是 PCRE 内部这些修饰符的名称。 + +> 模式修饰符中的空格,换行符会被忽略,其他字符会导致错误。 + +- `i (PCRE_CASELESS)` 如果设置了这个修饰符,`模式中的字母会进行大小写不敏感匹配` +- `m (PCRE_MULTILINE)` 默认情况下,PCRE 认为目标字符串是由单行字符组成的(然而实际上它可能会包含多行), +"行首"元字符 (`^`) 仅匹配字符串的开始位置, 而"行末"元字符 (`$`) 仅匹配字符串末尾,或者最后的换行符(除非设置了 `D` 修饰符)。 +这个行为和 perl 相同。 当这个修饰符设置之后,“行首”和“行末”就会匹配目标字符串中任意换行符之前或之后,另外, 还分别匹配目标字符串的最开始和最末尾位置。 +这等同于 perl 的 `/m` 修饰符。如果目标字符串 中没有 `\n` 字符,或者模式中没有出现 `^` 或 `$`,设置这个修饰符不产生任何影响。 +- `s (PCRE_DOTALL)` 如果设置了这个修饰符,模式中的点号元字符匹配所有字符,包含换行符。如果没有这个 修饰符,点号不匹配换行符。 +这个修饰符等同于 perl 中的 `/s` 修饰符。 一个取反字符类比如 `[^a]` 总是匹配换行符,而不依赖于这个修饰符的设置。 +- `x (PCRE_EXTENDED)` 如果设置了这个修饰符,模式中的没有经过转义的或不在字符类中的空白数据字符总会被忽略, 并且位于一个未转义的字符类外部的#字符和下一个换行符之间的字符也被忽略。 +这个修饰符 等同于 perl 中的 `/x` 修饰符,使被编译模式中可以包含注释。 注意:这仅用于数据字符。 +空白字符 还是不能在模式的特殊字符序列中出现,比如序列 `(?(` 引入了一个条件子组(译注: 这种语法定义的 特殊字符序列中如果出现空白字符会导致编译错误。 比如 `(?(`就会导致错误)。 +- `A (PCRE_ANCHORED)` 如果设置了这个修饰符,模式被强制为"锚定"模式,也就是说约束匹配使其仅从 **目标字符串的开始位置搜索**。 +这个效果同样可以使用适当的模式构造出来,并且 这也是 perl 种实现这种模式的唯一途径。 +- `D (PCRE_DOLLAR_ENDONLY)` 如果这个修饰符被设置,模式中的元字符美元符号仅仅匹配目标字符串的末尾。 +如果这个修饰符 没有设置,当字符串以一个换行符结尾时, `$` 还会匹配该换行符(但不会匹配之前的任何换行符)。 +如果设置了修饰符`m`,这个修饰符被忽略. 在 perl 中没有与此修饰符等同的修饰符。 +- `S` 当一个模式需要多次使用的时候,为了得到匹配速度的提升,值得花费一些时间 对其进行一些额外的分析。 +如果设置了这个修饰符,这个额外的分析就会执行。当前,这种对一个模式的分析 _仅仅适用于非锚定模式的匹配(即没有单独的固定开始字符)_。 +- `U (PCRE_UNGREEDY)` 这个修饰符逆转了量词的"贪婪"模式。 使量词默认为非贪婪的,通过量词后紧跟 `?` 的方式可以使其成为贪婪的。 +这和 perl 是不兼容的。 它同样可以使用 模式内修饰符设置 `(?U)` 进行设置, 或者在量词后以问号标记其非贪婪(比如 `.*?`) +- `X (PCRE_EXTRA)` 这个修饰符打开了 PCRE 与 perl 不兼容的附件功能。模式中的任意反斜线后就 `ingen` 一个 没有特殊含义的字符都会导致一个错误,以此保留这些字符以保证向后兼容性。 +默认情况下,在 perl 中,反斜线紧跟一个没有特殊含义的字符被认为是该字符的原文。 当前没有其他特性由这个修饰符控制。 +- `J (PCRE_INFO_JCHANGED)` 内部选项设置 `(?J)` 修改本地的 `PCRE_DUPNAMES` 选项。允许子组重名,(译注:只能通过内部选项设置,外部的 `/J` 设置会产生错误。) 自 PHP 7.2.0 起,也能支持 `J` 修饰符。 +- `u (PCRE_UTF8)` 此修正符打开一个与 Perl 不兼容的附加功能。 +模式和目标字符串都被认为是 UTF-8 的。 无效的目标字符串会导致 `preg_*` 函数什么都匹配不到; +无效的模式字符串会导致 E_WARNING 级别的错误。 5 字节和 6 字节的 UTF-8 字符序列以无效字符序列对待 + diff --git a/resource/packages.md b/resource/packages.md index 8e95b12..9ecd35a 100644 --- a/resource/packages.md +++ b/resource/packages.md @@ -18,8 +18,11 @@ composer require knplabs/github-api:^3.0 guzzlehttp/guzzle:^7.0.1 http-interop/h **markdown** -- `cebe/markdown` -- `league/commonmark` +- `cebe/markdown` https://github.com/michelf/php-markdown +- `erusev/parsedown` https://github.com/erusev/parsedown +- `league/commonmark` https://github.com/thephpleague/commonmark + - docs https://commonmark.thephpleague.com +- `michelf/php-markdown` https://github.com/michelf/php-markdown **html to markdown** diff --git a/resource/templates/gen-by-parse/gen-go-funcs.tpl b/resource/templates/gen-by-parse/gen-go-funcs.tpl index 0a9bed2..20acf72 100644 --- a/resource/templates/gen-by-parse/gen-go-funcs.tpl +++ b/resource/templates/gen-by-parse/gen-go-funcs.tpl @@ -1,5 +1,5 @@ # -# usage: kite gen parse @kite/resource/example/gen-go-funcs.tpl +# usage: kite gen parse @resource-tpl/gen-by-parse/gen-go-funcs.tpl # vars=[Info, Error, Warn]