infoxy / utext
一组小巧的PHP文本工具类。
Requires
- php: >=5.5.0
Requires (Dev)
- php: >=5.5.0
README
一组小巧的PHP文本工具类。
要求
- PHP intl 扩展或 Normalizer 类 和 idna 函数 的 polyfills。
类列表(所有类都放在 \infoxy\utext 命名空间
中)
- PlainFilter:纯文本过滤器及其对应工具。
- PlainSimpler:简化纯Unicode文本的过滤器。
- HtmlBase:用于 DOMDocument 操作的静态函数集合。
- IdnaURL:国际域名规范化和人文化类。
前两个类可以作为独立使用,后者基于其构建。
目的和简介
所有编辑器、抄写员、用户在HTML和Unicode方面都有不同的技能。有人使用记事本,有人使用文字处理器或在某些高级发布平台上打字,所有人都可以从外国来源复制粘贴,等等。
结果是现实生活中:许多简单的UTF-8文本(例如网站数据库中的文本)在格式和专业技术质量上可能非常不同
- 可能包含无效的UTF-8字节序列;
- 可能是复合和分解Unicode字符的混合;
- 带有或没有编码的HTML实体;
- 带有或没有非规范化空格;
- 带有特殊空格(空格、固定宽度空格),这对于打印纸张可能很好,但在网页上复制粘贴时可能很糟糕;
- 带有特殊破折号、连字符或其他符号,这些符号可能在使用字体中未发布。
这使得文本片段难以搜索且看起来很丑。PlainFilter 过滤器可以将纯文本转换为一些更规范和干净的形式(基于指定的选项),并提供一些附加服务,如标签剥离和模式使用。有关详细信息,请参阅 PlainFilter 部分。
PlainFilter
基本过滤
use \infoxy\utext\PlainFilter
$pf = new PlainFilter;
$pf -> setLangId('ru') // language for quote filter
-> setOptions([ // set filter options
'filter_utf8' => true,
'decode_entities' => true,
'lang_quotes' => true, // replace " with language-specific quotes
'replace_quotes => true, // replase ' and " to curly form
'simplify_spaces' => true,
'collapse_spaces' => true,
'trim' => true,
'normalize' => true,
]);
$filtered_string = $pf->filter($input_string);
在“逻辑管道”顺序中有过滤选项列表
filter_utf8 只跳过正确的UTF8字符,删除任何无效的字节序列。
注意:存在静态方法 PlainFilter::filter_utf8($s)
,可以显式使用。
newline_tags 在每个 <
前插入 \r\n
。与 strip_tags 一起使用时,可用于从HTML或XML生成非单词连接的纯文本。例如:"<em>yellow</em><b>green</b>"
将导致 "yellow green"
而不是 "yellowgreen"
。
strip_tags 剔除标签。可以与 newline_tags 一起使用。
decode_entities 解码HTML实体。所有编码的实体,如 —
或 ∫
,都将解码为适当的Unicode字符。
lang_quotes 用语言特定的双引号替换双引号。这是一个简单的基于语言的引号替换器。
支持的语言ID是:en
、de
、ru
、fr
。其他情况在当前版本中降级到 en
。
注意1:在本版本中,lang_quotes 只查找单词边界,因此一些嵌套和带空格的双引号可能会被错误处理。但即使现在,这也可能是一个非常有用的文本编写工具。
注意2:这是需要使用 setLangId()
进行语言特定设置的选项。
注意3:lang_quotes选项在需要时可以在引号周围生成额外的空格。
简化破折号 将破折号简化为连字符(u+2D)、短破折号(u+2013)或长破折号(u+2014)。许多字体没有完整的Unicode破折号集合。此选项可用于生成
- 连字符,从 u+2010(连字符),u+2011(非断开连字符)
- 短破折号,从 u+2012(数字破折号),
- 长破折号,从 u+2015(水平线),u+2E3A(双长划线),u+2E3B(三长划线)。
注意:数学负号 u+2212(负号)和语言特定的连字符/破折号保持不变。
shy_pattern 将 "TeX" 风格中的 \-
中的 shy 模式替换为 u+AD(软连字符)。
dash_patterns 替换破折号模式。此选项定义在 "TeX" 风格中使用长破折号和短破折号模式
--
到 u+2013(短破折号),---
到 u+2014(长破折号)。
replace_triple_dots 将三个点替换为 u+2026(省略号)。它可以与 trim_dots 一起使用。
replace_quotes 将直角单引号和双引号替换为花括号引号。
'
到 u+2019(高9引号),"
到 u+201D(高99引号)。
replace_specials 将特殊字符替换为安全的回退。这是一种既丑陋又防弹的解决方案,可防止HTML特殊字符。替换
&
到+
(加号),<
到 u+2039(左指单角引号),>
到 u+203A(右指单角引号)。
注意:全宽字符(如全宽和号)不被大多数字体广泛支持,所以我们不将其用作替换。
简化空格 简化空格。将空白字符、u+A0(空格)、u+2000 到 u+200A(固定宽度空格)、u+202F(窄空格)、u+205F(中等数学空格)替换为简单空格。
collapse_spaces 将空白序列替换为单个空格。
zebra_spaces 将成对的空格替换为 nbsp+空格。
注意:collapse_spaces 在逻辑上优于 zebra_spaces。
trim 去除前导和尾随空格。
trim_dots 去除前导和尾随点。在某些场景中,对于标题和描述字段可能很有用。与 replace_triple_dots 一起使用以去除点,但不去除三点。
normalize 将 Unicode 字符串规范化为规范化形式之一。默认形式为 Normalization Form C
即 NFC
。
大多数过滤选项是 PlainFilter::setOptions() 的标志。但一些附加设置可以通过特殊的设置器和获取器完成
setLangId($lang_id = NULL)
:设置语言特定的选项的语言,默认为 'en'。 getLangId()
:获取语言特定的选项的语言。
setNormalForm($nf = 'NFC')
:设置 Unicode 规范化形式。可以是 'NFC'、'NFD'、'NFKC'、'NFKD'。默认是 'NFC'。 getNormalForm()
:获取当前的 Unicode 规范化形式。
过滤转义
过滤转义提供在用户编辑场景中多次过滤字符串的能力。转义的主要事情是恢复 ampersand 的 &
实体和/或恢复所需的模式。重新过滤的字符串不会因双重解码而损坏。
use \infoxy\utext\PlainFilter;
// Note: same options as for filter,
// but language-specific and normalizer settings not needed
$opt = [
'filter_utf8' => true,
'decode_entities' => true,
'lang_quotes' => true, // replace " with language-specific quotes
'replace_quotes => true, // replase ' and " to curly form
'simplify_spaces' => true,
'collapse_spaces' => true,
'trim' => true,
'normalize' => true,
];
// Call static escape_filter()
$prepared_string = PlainFilter::escape_filter($input_string, $opt);
PlainSimpler
Unicode 纯文本简化器。
PlainSimpler::simplify($s, $lang)
简化 Unicode 纯文本。通常这不是您希望向最终用户暴露的内容。简化后的文本可以用于改进搜索查询和字符串比较。
更深入地简化()做
- 解码 HTML 实体;
- 通过规范化为 NFKD 分解双字母和连字符;
- 针对 umlauts、AE 等(基于拉丁语的)进行额外的基于语言的分解。
- 保留一些特定的重音组合(西里尔 'Й')。
- 删除所有其他重音符号。
- 最后,规范化为 NFC。
注意:PlainSimpler 可以作为 PlainFilter 的下一阶段使用。
PlainSimpler 示例
use \infoxy\utext\PlainSimpler;
...
$src = "bœf (fr), el niño (es), клёвый (ru), regelmäßig (de), øjemål (da)";
$simp_en = PlainSimpler::simplify($src, 'en');
// Produce "boef (fr), el ninno (es), клевый (ru), regelmassig (de), oejemal (da)"
$simp_de = PlainSimpler::simplify($src, 'de');
// Produce "boef (fr), el ninno (es), клевый (ru), regelmaessig (de), oejemaal (da)"
HtmlBase
一组用于 DOMDocument 操作的静态函数。因此,您不需要创建 HtmlBase 对象即可使用方法。
注意:toText()
和 toDom()
专注于导入/导出正文中的 HTML 标签,而不是包含嵌入式脚本、样式和 CDATA 部分的完整文档。
字符串到DOM和反向
HtmlBase::toDom($s) 从字符串 $s 创建 HTML DOMDocument,该字符串定义了创建的文档的体内容。返回创建的文档的 body DOMElement。
HtmlBase::toText($e) 将 DOMElement $e 的内容导出到字符串中。返回 html 字符串。
类检查
HtmlBase::classCheck($s) 检查字符串 $s 是否可作为类列表接受。在当前版本中,这意味着 $s 包含字母数字、'-'、下划线和空格的混合。如果检查通过,则返回 TRUE,否则返回 FALSE。
HtmlBase::classArray($s) 将字符串 $s 分解为类名。返回字符串数组(如果没有类,则返回空数组)。
HtmlBase::classPat($classes) 生成匹配指定类的模式。$classes:类名数组或类名字符串。
使用示例
$pat = HtmlBase::classPat('class1 class2 class3');
foreach ($nodes as $n) {
if ($n->hasAttribute('class') && preg_match($pat, $n->getAttribute('class'))) {
// class matched with any of ones in pattern
// DoSomething($n);
}
}
DOM元素操作
HtmlBase::tagStrip($e) 移除标签(DOMElement)$e,将其子节点重新附加到其父节点。返回重新附加的第一个子节点(如果没有子节点或 $e 没有父节点,则返回 NULL)。
HtmlBase::tagWrap($e, $tag) 使用新的 DOMElement(具有字符串 $tag 名称)包装(DOMElement)$e。返回新创建的 DOMElement。
HtmlBase::tagReplace($e, $tag) 用具有字符串 $tag 名称的新 DOMElement 替换(DOMElement)$e,并将子节点重新附加到它。id、class、lang、dir 属性也复制到新元素。返回新创建的 DOMElement。
HtmlBase::contentWrap($e,$tag) 使用指定的标签包装(DOMElement)$e 的子节点。返回:新创建的 DOMElement
IdnaURL
... 进行中 ...