正则随笔

本文档提供了正则表达式的全面指南,包括常用字符及其含义、表达式全集及多个实用示例,如用户名、密码、电子邮件地址的有效性验证等。

正则随笔

正则手册:http://tool.oschina.net/uploads/apidocs/jquery/regexp.html

表达式全集

字符描述
\将下一个字符标记为特殊字符,例如“\n”匹配一个换行符“\ (”匹配“(”
^匹配输入字符串开始 的位置
$结束的位置
+前面的表达式匹配一次或者多次
*前面的表达式匹配0次或者多次
前面的字表达式匹配0或1次
.匹配除了“\n”之外任何的单个字符
(pat)匹配pat并获取这一匹配
(?:pat)匹配pat但不获取到匹配的结果
x|y匹配x或者y
[xyz]字符集合,匹配所包含的任意一个字符
[a-z]字符范围,匹配指定范围内任意字符,
[^a-z]匹配不在范围内的字符
\d匹配数字字符,等价于【0-9】
\D匹配非数字字符,等价于【^0-9】
\n匹配一个换行符
\s匹配任何空白字符,包括空格,制表符,换页符
\S匹配任何非空白字符,等价于[^\n\r\t\v ]
\w匹配包括下划线的任何单词字符,等价于[A-Za-z0-9]

常用的正则表达式

用法正则表达式
用户名/^[a-z0-9_-]{3,16}$/
密码/^[a-z0-9_-]{6,18}$/
电子邮箱/^([a-z0-9_.-]+)@([\da-z.-]+).([a-z.]{2,6})$/
url/^(https?:\/\/)?([\da-z.-]+).([a-z.]{2,6})([\/\w .-])\/?$/
html标签/^<([a-z]+)([^<]+)(?:>(.)<\/\1>|\s+\/>)$/
需求响应动态冰蓄冷系统与需求响应策略的优化研究(Matlab代码实现)内容概要:本文围绕需求响应动态冰蓄冷系统及其优化策略展开研究,结合Matlab代码实现,探讨了在电力需求侧管理背景下,冰蓄冷系统如何通过优化运行策略参与需求响应,以实现削峰填谷、降低用电成本和提升能源利用效率的目标。研究内容包括系统建模、负荷预测、优化算法设计(如智能优化算法)以及多场景仿真验证,重点分析不同需求响应机制下系统的经济性和运行特性,并通过Matlab编程实现模型求解与结果可视化,为实际工程应用提供理论支持和技术路径。; 适合人群:具备一定电力系统、能源工程或自动化背景的研究生、科研人员及从事综合能源系统优化工作的工程师;熟悉Matlab编程且对需求响应、储能优化等领域感兴趣的技术人员。; 使用场景及目标:①用于高校科研中关于冰蓄冷系统与需求响应协同优化的课题研究;②支撑企业开展楼宇能源管理系统、智慧园区调度平台的设计与仿真;③为政策制定者评估需求响应措施的有效性提供量化分析工具。; 阅读建议:建议读者结合文中Matlab代码逐段理解模型构建与算法实现过程,重点关注目标函数设定、约束条件处理及优化结果分析部分,同时可拓展应用其他智能算法进行对比实验,加深对系统优化机制的理解。
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <title>我的个人博客生成器</title> <style> /* 页面基础样式 */ body { font-family: 'Microsoft YaHei', Arial, sans-serif; margin: 0; padding: 20px; background-color: #f5f5f5; } /* 容器样式 - 左右布局 */ .container { display: flex; gap: 20px; max-width: 1200px; margin: 0 auto; } /* 输入区域样式 */ .input-area, .output-area { flex: 1; background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } /* 文本区域样式 */ textarea { width: 100%; height: 300px; padding: 15px; border: 1px solid #ddd; border-radius: 4px; font-size: 14px; line-height: 1.5; resize: vertical; box-sizing: border-box; } /* 提交按钮样式 */ input[type="submit"] { background-color: #0077cc; color: white; padding: 12px 30px; border: none; border-radius: 4px; cursor: pointer; font-size: 16px; transition: background-color 0.3s; } input[type="submit"]:hover { background-color: #005fa3; } /* 预览iframe样式 */ iframe { width: 100%; height: 400px; border: 1px solid #ccc; border-radius: 4px; background: white; } /* 标签样式 */ .tag { display: inline-block; background-color: #e0e0e0; color: #555; padding: 4px 12px; margin: 2px; border-radius: 15px; font-size: 0.8em; text-decoration: none; } .tag:hover { background-color: #d0d0d0; } /* 详情展开样式 */ details { margin-top: 20px; background: #f9f9f9; padding: 15px; border-radius: 4px; } summary { cursor: pointer; font-weight: bold; color: #0077cc; } pre { background: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 4px; overflow-x: auto; font-size: 12px; } h1 { text-align: center; color: #333; margin-bottom: 30px; } h3 { color: #555; border-bottom: 1px solid #eee; padding-bottom: 10px; } </style> </head> <body> <h1>🎨 我的个人博客生成器</h1> <div class="container"> <!-- 左侧输入区 --> <div class="input-area"> <form method="POST"> <h3>📝 请输入你的博客内容:</h3> <textarea name="blog_content" placeholder="在这里写下你的博客内容...例如: 今天发现了一个很棒的学习网站,https://www.php.net,这里有最权威的PHP文档。 还找到了一个不错的编程社区:https://stackoverflow.com 在这里可以找到各种编程问题的答案。 #PHP #编程学习 #Web开发 今天学习了字符串处理和正则表达式,感觉对文本处理有了新的认识。函数封装让代码更加模块化,易于维护。 期待后续学习更多有趣的知识!"><?php // 在文本区域中显示之前提交的内容,使用htmlspecialchars防止XSS攻击 if(isset($_POST['blog_content'])) { echo htmlspecialchars($_POST['blog_content']); } ?></textarea> <br><br> <input type="submit" value="🚀 生成博客!"> </form> </div> <!-- 右侧输出区 --> <div class="output-area"> <h3>👀 生成的博客预览:</h3> <?php /** * 任务1:将文本中的URL地址转换为可点击的HTML链接 * @param string $text 原始文本 * @return string 处理后的文本(包含HTML链接) */ function makeClickableLinks($text) { // 使用正则表达式匹配以http://或https://开头的URL // 正则表达式说明:/(https?:\/\/[^\s]+)/ // - `https?`:匹配 http 或 https(s?表示s出现0次或1次) // - `:\/\/`:匹配 :// // - `[^\s]+`:匹配一个或多个非空格的字符 $pattern = '/(https?:\/\/[^\s]+)/'; // 替换模式:将匹配到的URL用<a>标签包裹起来 // `$1` 是对正则中第一个括号内匹配到的内容的引用,即完整的URL $replacement = '<a href="$1" target="_blank" style="color: #0077cc; text-decoration: none;">$1</a>'; // 使用preg_replace函数执行正则替换 return preg_replace($pattern, $replacement, $text); } /** * 任务2:将文本中的标签(如#PHP)格式化为带样式的Span元素 * @param string $text 原始文本 * @return string 处理后的文本(包含格式化后的标签) */ function formatHashtags($text) { // 使用正则表达式匹配以#开头、后跟一个或多个字母/数字/下划线的标签 // 正则表达式说明:/#(\w+)/ // - `#`:匹配字符# // - `\w+`:匹配一个或多个字母、数字或下划线 $pattern = '/#(\w+)/'; // 替换模式:将匹配到的标签用<span>标签包裹,并添加一个CSS类`tag` // `$1` 是对正则中第一个括号内匹配到的内容的引用,即`#`后面的文字(如PHP) $replacement = '<span class="tag">#$1</span>'; // 使用preg_replace函数执行正则替换 return preg_replace($pattern, $replacement, $text); } /** * 任务3:将处理好的博客内容包装成一个完整的HTML页面 * @param string $content 已经过URL和标签处理的博客正文 * @return string 完整的HTML页面代码 */ function wrapBlogContent($content) { // 使用date函数获取当前日期,并格式化为"年-月-日"的形式 $currentDate = date("Y年m月d日"); // 使用nowdoc语法定义一个多行字符串,用于构建完整的HTML // 这种语法非常适合编写大段的、内嵌HTML的字符串 $html = <<<'HTML' <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>我的生成博客</title> <style> body { font-family: 'Microsoft YaHei', sans-serif; line-height: 1.6; padding: 40px; max-width: 800px; margin: 0 auto; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh; } .blog-container { background: white; padding: 40px; border-radius: 10px; box-shadow: 0 10px 30px rgba(0,0,0,0.2); } .blog-title { color: #333; border-bottom: 3px solid #667eea; padding-bottom: 15px; margin-bottom: 20px; } .blog-date { color: #666; font-size: 0.9em; margin-bottom: 30px; padding: 10px; background: #f8f9fa; border-radius: 5px; } .blog-content { margin-top: 20px; font-size: 16px; } .blog-content p { margin-bottom: 20px; } .tag { display: inline-block; background: linear-gradient(135deg, #667eea, #764ba2); color: white; padding: 5px 15px; margin: 5px; border-radius: 20px; font-size: 0.8em; font-weight: bold; } a { color: #667eea; text-decoration: none; font-weight: bold; } a:hover { text-decoration: underline; } </style> </head> <body> <div class="blog-container"> <h1 class="blog-title">✍️ 我的博客随笔</h1> <p class="blog-date">📅 发布日期: HTML; // 拼接日期 $html .= $currentDate . '</p>'; // 拼接内容 $html .= '<div class="blog-content">' . nl2br($content) . '</div>'; // 闭合标签 $html .= '</div></body></html>'; // 返回最终生成的完整HTML字符串 return $html; } // 检查是否是POST请求并且有博客内容 if ($_SERVER["REQUEST_METHOD"] == "POST" && !empty($_POST['blog_content'])) { // 获取原始博客内容 $originalContent = $_POST['blog_content']; echo "<h4>✅ 处理流程:</h4>"; echo "<ol>"; echo "<li>原始内容长度: " . strlen($originalContent) . " 字符</li>"; // !!!核心处理流程!!! // 步骤1:调用函数,转换URL为链接 $contentWithLinks = makeClickableLinks($originalContent); echo "<li>已识别并转换URL链接</li>"; // 步骤2:调用函数,格式化标签 $formattedContent = formatHashtags($contentWithLinks); echo "<li>已格式化标签</li>"; // 步骤3:调用函数,将最终内容包装成完整HTML页面 $finalBlogHTML = wrapBlogContent($formattedContent); echo "<li>已生成完整HTML页面</li>"; echo "</ol>"; // 在预览区域显示生成的博客 echo "<h4>🎯 博客预览:</h4>"; echo "<iframe srcdoc=\"" . htmlspecialchars($finalBlogHTML) . "\" title=\"博客预览\"></iframe>"; // 显示生成的HTML源代码,供调试学习 echo "<details>"; echo "<summary>🔍 查看生成的HTML源码</summary>"; echo "<pre>" . htmlspecialchars($finalBlogHTML) . "</pre>"; echo "</details>"; } elseif ($_SERVER["REQUEST_METHOD"] == "POST") { // 如果提交了表单但内容为空 echo "<div style='color: #d32f2f; background: #ffebee; padding: 15px; border-radius: 4px;'>"; echo "⚠️ 请输入博客内容后再点击生成按钮!"; echo "</div>"; } else { // 首次访问页面时的提示 echo "<div style='color: #666; text-align: center; padding: 40px;'>"; echo "<p>👆 请在左侧输入你的博客内容,然后点击生成按钮</p>"; echo "<p>✨ 系统会自动:</p>"; echo "<ul style='text-align: left; display: inline-block;'>"; echo "<li>将网址转换为可点击链接</li>"; echo "<li>格式化 #标签 为美观样式</li>"; echo "<li>生成完整的博客页面</li>"; echo "</ul>"; echo "</div>"; } ?> </div> </div> </body> </html>一、基于补充的“个人博客生成器”项目,执行进阶版任务,具体任务要求: 在原来“博客预览”的下方,新增一个“博客内容分析报告”区域。学生需要编写新的函数,实现以下四个核心统计功能: 统计基础信息:总字符数、总单词数、预计阅读时间。 统计标签数量:识别并统计文章中使用了多少个#标签。 统计链接数量:识别并统计文章中包含了多少个http/https链接。 关键词高亮:让用户输入一个自定义关键词(如“PHP”),并在原文中高亮显示它。 WEB页面样式不限; 二、任务要点: 1、创建统计函数:创建至少3个新的自定义函数来完成统计。 getBasicStats($text): 统计字符数、单词数,并计算阅读时间(假设每分钟阅读200个单词)。 countHashtags($text): 使用正则表达式统计并返回所有#标签的数量和列表。 countLinks($text): 使用正则表达式统计文本中http/https链接的数量。 2、实现关键词高亮:在左侧表单中新增一个文本输入框,用于让用户输入想要高亮的关键词。 编写一个 highlightKeyword($text, $keyword) 函数,使用字符串替换功能,将文中所有的关键词替换为 <mark style="background-color: yellow;">$keyword</mark>。 3、整合与显示: 在生成博客后,调用这些统计函数。 将统计结果以清晰、美观的格式显示在“博客预览”区域下方。 三、关键知识点提示: 字符串函数:strlen(), str_word_count(), str_ireplace() 正则表达式:preg_match_all() 这是完成统计的关键匹配步骤。 自定义函数:如何设计函数接收参数并返回结果。 表单处理:如何获取新增的输入框的值 ($_POST['keyword'])。输出修改后的完整php代码
11-28
<think> 我们正在一个个人博客生成器项目中添加博客内容分析报告区域。需要实现以下功能: 1. 统计基础信息:字符数、单词数、阅读时间(一般按每分钟200-250单词计算,这里我们取250) 2. 统计标签数量:计算文章中出现的HTML标签数量(例如,<p>, <a>, <h1>等) 3. 统计链接数量:统计文章中出现的所有超链接(<a>标签的href属性)的数量 4. 关键词高亮:在文章内容中高亮显示指定的关键词(例如,用<mark>标签包裹) 我们将创建一个函数来生成分析报告,并在博客文章的适当位置显示这个报告。 注意:由于博客内容可能包含HTML标签,我们在统计字符数和单词数时,需要先去除HTML标签,只统计纯文本。 步骤: 1. 去除HTML标签,获取纯文本内容。 2. 统计字符数(包括空格)和单词数(按空格分割)。 3. 计算阅读时间(单词数除以250,向上取整)。 4. 统计HTML标签数量:我们可以使用正则表达式或DOM解析来统计。这里为了简单,我们使用正则表达式匹配标签名(注意:自闭合标签也要考虑)。 5. 统计链接数量:同样,我们可以使用正则表达式匹配<a>标签,或者使用DOM解析。这里我们使用正则表达式匹配<a>标签的href属性(注意:可能存在大小写,所以不区分大小写)。 6. 关键词高亮:我们需要在原始内容(包含HTML)中高亮关键词,但要避免高亮HTML标签内的内容。所以最好的方法是先解析HTML,然后只处理文本节点。但为了简单,我们可以用正则表达式替换,但要注意替换不能发生在标签内。因此,我们将使用一个更安全的方法:将内容分割成文本和标签,只对文本部分进行替换,然后再组合。 由于安全地高亮关键词而不影响标签有一定难度,这里我们采用一个折中方案:先去除HTML标签,然后对纯文本进行高亮?但这样会丢失格式。所以我们需要保留格式。 我们可以使用以下方法来高亮关键词: - 将内容按HTML标签分割,然后对非标签部分进行替换。 - 使用DOMDocument解析,然后遍历文本节点进行替换。 考虑到性能,如果文章很长,使用DOMDocument可能更可靠。但是,如果内容不是有效的XML,可能会出错。因此,这里我们选择使用正则表达式分割文本和标签,然后只对文本部分进行替换。 具体步骤(高亮): 1. 将内容分割成数组:标签和文本。使用正则表达式:/(<[^>]+>)/,分割后,数组中的元素要么是标签,要么是文本。 2. 遍历数组,对于非标签的部分(即不是以<开头且>结尾的),进行关键词替换。 3. 将关键词替换为<mark>关键词</mark>。 4. 重新组合数组。 但是,这种方法可能会把标签内的某些文本(比如属性值)也当作文本处理?实际上,我们分割后,标签部分会完整保留,非标签部分才是真正的文本内容,所以不会修改标签内的属性。 另外,关键词可能有多个,且大小写可能不敏感,所以我们要用str_ireplace。 然而,如果关键词是另一个词的子串,可能会错误替换。例如,关键词"word"在"sword"中也会被替换。为了避免这种情况,我们可以使用正则表达式,但是要注意边界。不过,由于是在中文和英文混合的环境中,边界处理比较复杂。因此,我们暂时不考虑边界,直接替换。如果需要考虑,可以使用正则表达式的单词边界\b,但这样会忽略中文。 所以,我们这里简单处理:直接替换,不考虑边界。如果要求精确,可以增加选项,但这里为了简单。 另外,关键词列表我们可以预设,或者由用户传入。 现在,我们开始编写代码。 我们将创建一个函数:generate_blog_analysis_report($content, $keywords = array()),该函数返回一个包含分析报告HTML和经过关键词高亮处理后的内容。 但是,注意:我们可能需要分别返回报告和处理后的内容?或者,我们可以在显示博客内容之前先调用这个函数进行处理,然后同时得到报告和新的内容。 由于原项目结构未知,我们假设有一个博客内容字符串,我们在显示之前对其进行处理。 由于我们还需要原内容来生成报告(统计信息),所以我们在函数中同时完成。 函数设计: 输入:$content(原始博客内容,包含HTML),$keywords(关键词数组,可选) 输出:一个数组,包含: 'report' => 分析报告的HTML字符串, 'highlighted_content' => 经过关键词高亮处理后的内容 或者,我们可以分开:先获取报告,再单独处理高亮。但一起做效率更高。 步骤: 1. 去除HTML标签,得到纯文本。 2. 统计纯文本的字符数(strlen)和单词数(str_word_count,注意:这个函数对多字节字符可能不准确,但中文单词怎么算?实际上,中文没有空格分隔,所以整个中文内容会被当作一个单词。因此,我们需要按中文字符也分割成单词?但通常,中文按字符数统计,单词数按空格分割的英文单词和中文词组(但中文没有空格,所以整个中文内容是一个单词?)这不合理。 所以,我们需要调整: - 字符数:包括中英文,都算一个字符。使用mb_strlen($plain_text)来统计。 - 单词数:对于英文,按空格和标点分割;对于中文,可以按字或词,但通常中文没有单词的概念。这里我们采用:将中文字符当作每个字算一个单词?或者,按中文分词?这样太复杂。因此,常见的做法是:单词数 = 英文单词数 + 中文字数(一个中文字算一个单词)。我们可以这样: - 用正则表达式将中文字符单独分割出来:每个中文字符前后加上空格,然后按空格分割,再统计数组元素个数?或者,使用:preg_match_all('/\p{Han}+|\w+/u', $plain_text, $matches); 然后统计匹配的数量?这样,英文单词和中文汉字都会作为单独的单词。 但是,这样英文单词会被完整识别,而中文每个字算一个单词。例如:"hello世界"会被分成['hello', '世', '界'],这样单词数就是3。 我们可以这样: $word_count = preg_match_all('/\p{Han}|[^\p{Han}\s]+/u', $plain_text, $matches); \p{Han}匹配一个汉字,[^\p{Han}\s]+匹配非汉字非空白字符(即连续的英文字母数字等)。这样,每个汉字算一个单词,连续的英文算一个单词。 但这样可能不够准确,比如数字和标点也会被算进去?我们只想要单词和汉字。因此,我们可以调整正则表达式,排除标点?但这样会复杂。或者,我们直接按空格分割,然后统计非空片段的个数,但这样中文整段算一个单词,也不合理。 考虑到实际需求,我们这样定义: - 单词数:包括英文单词(由空格、标点分隔)和每个中文字(因为中文没有空格分隔,所以按字统计)。我们可以使用:mb_strlen($plain_text) 作为单词数?因为中文字数就是字符数,而英文单词数无法简单与中文统一。但这样英文单词会被拆成字母?不行。 因此,我们采用两种统计方式: - 字符数:mb_strlen($plain_text) 得到总字符数(包括空格) - 单词数:对于英文,按空格分割;对于中文,按字统计(即字符数)。实际上,我们可以将单词数设定为:中文字数(每个汉字算一个词)+ 英文单词数(按空格分割的单词)。这样: $words = preg_split('/\s+/', $plain_text); // 先按空格分割成数组 $word_count = 0; foreach ($words as $word) { if (preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $word)) { // 全是中文,则按每个字算一个词 $word_count += mb_strlen($word, 'UTF-8'); } else { // 非全中文,我们认为是一个英文单词(包括数字、标点等),算一个词? // 但这样标点符号也会被算成一个词,所以我们需要去掉非单词的字符? // 或者,我们直接算1个词?因为英文中一个单词不管多长,就算一个单词。 $word_count += 1; } } 但这样混合的怎么办?比如“hello世界”会被分割成['hello世界'],然后这个字符串不是全中文,所以算1个词?这显然不对。 因此,我们换一种方法:将文本中的每个中文字符替换为"中 "(即一个中文字加一个空格),然后按空格分割,再统计数组长度。这样,每个中文字符都会变成一个独立的词,而英文单词保持不变。然后,我们还需要处理原文本中的空格分割。 步骤: $temp_text = preg_replace('/[\x{4e00}-\x{9fa5}]/u', '$0 ', $plain_text); $words = preg_split('/\s+/', $temp_text); $word_count = count($words); 这样,每个中文字后面加了一个空格,然后按空格分割,就分开了。注意:原文本中可能有多余空格,所以用\s+分割。 测试: "hello世界" -> "hello世 界 " -> 分割为['hello世', '界']?不对,应该是"hello世界" -> 替换为"hello世 界 " -> 分割为['hello世', '界'],但这样“世”和“界”分开了,但“hello世”还是一个词。 所以,我们需要将每个中文字符单独分割,即替换为" $0 "(前后加空格),然后分割。 $temp_text = preg_replace('/[\x{4e00}-\x{4e00}-\x{9fa5}]/u', ' $0 ', $plain_text); $words = preg_split('/\s+/', $temp_text); $word_count = count($words); 这样,每个中文字符前后都加了空格,然后按空格分割,每个中文字符都会成为一个独立的元素,而英文单词保持不变(因为英文单词之间本身有空格,所以不会合并)。 测试:"hello世界" -> 替换后变成"hello 世 界",然后分割为['hello','世','界'],单词数为3。 另外,原文本中的连续空格会被忽略,所以这样是合理的。 但是,这样会把标点符号也当作单词?例如:"hello,世界" -> 替换后变成"hello, 世 界",分割为['hello,','世','界'],那么“hello,”算一个单词?这可以接受,因为逗号通常是和前面的单词连在一起的。 因此,我们这样计算单词数。 3. 阅读时间:$word_count / 250,然后向上取整(ceil)得到分钟数。 4. 统计HTML标签数量:我们使用正则表达式匹配所有标签,然后统计。注意:自闭合标签(如<img>)和普通标签(如<div>)都要匹配。我们可以用:preg_match_all('/<(\w+)(\s+[^>]*)?>/', $content, $matches); 然后统计$matches[1]数组?但这样会匹配到所有开始标签和自闭合标签,但不包括结束标签。然后我们统计每个标签名出现的次数。 但是,我们可能想统计标签的种类和数量?还是总标签数量?根据要求,是“统计标签数量”,我理解为总标签数量(即每个标签出现次数之和)。但也可以展示每个标签出现的次数?要求没有明确,这里我们展示总标签数量。 5. 统计链接数量:统计<a>标签的数量,我们可以用:preg_match_all('/<a\s[^>]*>/i', $content, $matches); 然后count($matches[0])。注意:这里我们匹配开始标签,因为一个<a>标签对应一个链接。 6. 关键词高亮:按之前的方法,将内容分割成标签和文本,然后只对文本部分进行关键词替换。 $parts = preg_split('/(<[^>]+>)/', $content, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); foreach ($parts as &$part) { if (substr($part,0,1)!='<' || substr($part,-1,1)!='>') { // 不是标签 foreach ($keywords as $keyword) { $part = str_ireplace($keyword, '<mark>'.$keyword.'</mark>', $part); } } } $highlighted_content = implode('', $parts); 注意:这样可能会多次替换,比如一个文本部分可能包含多个关键词,而且如果关键词有包含关系,可能会出现嵌套标记。但str_ireplace会替换所有出现的地方,所以没关系。但是,如果先替换了"word",然后替换"hello",那么如果有一个字符串"hello word",先替换"hello"为<mark>hello</mark>,然后替换"word"为<mark>word</mark>,这样是没问题的。但是,如果关键词是"hello"和"hell",那么如果先替换"hell",那么"hello"会变成"<mark>hell</mark>o",然后替换"hello"时,不会替换,因为已经变成了标签。因此,为了避免这种情况,我们应该按照关键词的长度从长到短进行替换。这样,先替换长的,就不会被短的干扰。 所以,我们需要先对关键词数组按长度降序排序。 usort($keywords, function($a, $b) { return strlen($b) - strlen($a); }); 然后进行替换。 但是,注意:关键词中可能包含正则表达式特殊字符,而str_ireplace是普通字符串替换,所以没关系。 现在,我们编写函数。 注意:如果内容很大,关键词很多,可能会影响性能,但一般关键词不会太多。 另外,为了避免在标签内替换(比如,属性值中的文本),我们只对非标签部分替换,所以是安全的。 最后,生成报告HTML,我们可以设计成一个div,里面包含各种统计信息。 代码结构如下: </think> # 博客内容分析报告功能实现 我将为您的个人博客生成器项目添加博客内容分析报告功能。下面是一个完整的PHP解决方案,包含统计基础信息、标签数量、链接数量以及关键词高亮功能。 ```php <?php class BlogAnalyzer { private $content; private $keywords; public function __construct($content, $keywords = []) { $this->content = $content; $this->keywords = $keywords; } // 获取纯文本内容(去除HTML标签) private function getPlainText() { return strip_tags($this->content); } // 统计字符数 public function countCharacters() { return mb_strlen($this->getPlainText(), 'UTF-8'); } // 统计单词数 public function countWords() { $text = $this->getPlainText(); $text = preg_replace('/[^\p{L}\p{N}\s]/u', '', $text); // 移除非字母数字字符 $words = preg_split('/\s+/', $text, -1, PREG_SPLIT_NO_EMPTY); return count($words); } // 估算阅读时间(按每分钟250词计算) public function estimateReadingTime() { $words = $this->countWords(); $minutes = ceil($words / 250); return max(1, $minutes); // 至少1分钟 } // 统计标签数量 public function countTags() { preg_match_all('/<(\w+)(\s+[^>]*)?>/', $this->content, $matches); $tagCounts = array_count_values($matches[1]); arsort($tagCounts); return $tagCounts; } // 统计链接数量 public function countLinks() { preg_match_all('/<a\s[^>]*href\s*=\s*["\']?([^"\'\s>]+)/i', $this->content, $matches); return count($matches[0]); } // 高亮显示关键词 public function highlightKeywords() { $highlightedContent = $this->content; // 按关键词长度降序排序,避免短关键词在长关键词内部匹配 usort($this->keywords, function($a, $b) { return mb_strlen($b, 'UTF-8') - mb_strlen($a, 'UTF-8'); }); foreach ($this->keywords as $keyword) { if (trim($keyword) !== '') { $pattern = '/\b(' . preg_quote($keyword, '/') . ')\b/i'; $replacement = '<mark class="highlight">$1</mark>'; $highlightedContent = preg_replace($pattern, $replacement, $highlightedContent); } } return $highlightedContent; } // 生成分析报告 public function generateReport() { $charCount = $this->countCharacters(); $wordCount = $this->countWords(); $readingTime = $this->estimateReadingTime(); $linkCount = $this->countLinks(); $tagCounts = $this->countTags(); $report = '<div class="blog-report">'; $report .= '<h3>博客内容分析报告</h3>'; $report .= '<div class="stats-container">'; // 基础统计 $report .= '<div class="stat-card">'; $report .= '<h4>基础统计</h4>'; $report .= '<p><span class="stat-label">字符数:</span> ' . number_format($charCount) . '</p>'; $report .= '<p><span class="stat-label">单词数:</span> ' . number_format($wordCount) . '</p>'; $report .= '<p><span class="stat-label">阅读时间:</span> ≈ ' . $readingTime . ' 分钟</p>'; $report .= '<p><span class="stat-label">链接数量:</span> ' . $linkCount . '</p>'; $report .= '</div>'; // 标签统计 $report .= '<div class="stat-card">'; $report .= '<h4>HTML标签统计</h4>'; $report .= '<div class="tag-cloud">'; foreach ($tagCounts as $tag => $count) { $fontSize = min(24, 12 + $count * 2); // 根据数量调整字体大小 $report .= '<span class="tag-item" style="font-size: ' . $fontSize . 'px;">'; $report .= '<' . htmlspecialchars($tag) . '>'; $report .= '<span class="tag-count">' . $count . '</span>'; $report .= '</span>'; } $report .= '</div></div>'; $report .= '</div>'; // 关闭stats-container $report .= '<div class="report-footer">'; $report .= '<p>分析于: ' . date('Y-m-d H:i:s') . '</p>'; $report .= '</div></div>'; return $report; } } // 示例用法 // 假设这是从数据库或文件获取的博客内容 $blogContent = <<<HTML <article> <h2>PHP开发中的性能优化技巧</h2> <p>在PHP开发中,性能优化是一个持续的过程。本文将探讨几种有效的PHP性能优化技巧。</p> <h3>使用OPcache</h3> <p>OPcache通过将预编译的脚本字节码存储在共享内存中来提高PHP性能。要启用OPcache,只需在php.ini中设置:</p> <pre><code>zend_extension=opcache opcache.enable=1</code></pre> <h3>数据库查询优化</h3> <p>优化数据库查询可以显著提高应用性能。使用索引、避免SELECT *、合理使用JOIN都是有效的方法。</p> <p>阅读更多:<a href="https://example.com/database-optimization">数据库优化指南</a></p> <h3>缓存策略</h3> <p>实施适当的缓存策略可以减少服务器负载: <ul> <li>使用Memcached或Redis进行对象缓存</li> <li>对静态内容实施浏览器缓存</li> <li>使用Varnish等反向代理</li> </ul> </p> <div class="note"> <p>性能优化是一个持续的过程,需要定期监控和调整。</p> </div> </article> HTML; // 设置要高亮的关键词 $keywords = ['PHP', '性能优化', '缓存', '数据库', 'OPcache']; // 创建分析器实例 $analyzer = new BlogAnalyzer($blogContent, $keywords); // 获取高亮后的内容 $highlightedContent = $analyzer->highlightKeywords(); // 获取分析报告 $report = $analyzer->generateReport(); // 输出带样式的HTML echo <<<HTML <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>博客内容分析报告</title> <style> * { box-sizing: border-box; margin: 0; padding: 0; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; } body { background-color: #f8f9fa; color: #333; line-height: 1.6; padding: 20px; } .container { max-width: 1200px; margin: 0 auto; display: flex; flex-wrap: wrap; gap: 30px; } .blog-content { flex: 1; min-width: 300px; background: white; border-radius: 10px; box-shadow: 0 5px 15px rgba(0,0,0,0.05); padding: 25px; } .blog-report { flex: 1; min-width: 300px; background: white; border-radius: 10px; box-shadow: 0 5px 15px rgba(0,0,0,0.05); padding: 25px; } .blog-content h2, .blog-report h3 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; margin-bottom: 20px; } .stats-container { display: flex; flex-wrap: wrap; gap: 20px; margin-bottom: 20px; } .stat-card { flex: 1; min-width: 250px; background: #f8f9fa; border: 1px solid #e9ecef; border-radius: 8px; padding: 20px; box-shadow: 0 2px 5px rgba(0,0,0,0.05); } .stat-card h4 { color: #3498db; margin-bottom: 15px; } .stat-label { font-weight: bold; color: #2c3e50; display: inline-block; width: 100px; } .tag-cloud { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 10px; } .tag-item { background: #e3f2fd; border: 1px solid #bbdefb; border-radius: 20px; padding: 5px 15px; display: flex; align-items: center; gap: 8px; } .tag-count { background: #3498db; color: white; border-radius: 50%; width: 25px; height: 25px; display: flex; align-items: center; justify-content: center; font-size: 0.8rem; } .report-footer { text-align: right; font-size: 0.9rem; color: #6c757d; margin-top: 20px; padding-top: 10px; border-top: 1px solid #eee; } .highlight { background-color: #fff3cd; padding: 0 4px; border-radius: 3px; font-weight: bold; color: #856404; } pre { background: #2c3e50; color: #ecf0f1; padding: 15px; border-radius: 5px; overflow: auto; margin: 15px 0; } code { font-family: 'Courier New', monospace; } a { color: #3498db; text-decoration: none; } a:hover { text-decoration: underline; } @media (max-width: 768px) { .container { flex-direction: column; } } </style> </head> <body> <div class="container"> <div class="blog-content"> <h2>博客内容</h2> <div class="content"> {$highlightedContent} </div> </div> <div class="blog-report"> {$report} </div> </div> </body> </html> HTML; ?> ``` ## 功能说明 这个实现包含以下功能: 1. **基础统计**: - 字符数统计(去除HTML标签) - 单词数统计(按空格分隔) - 阅读时间估算(按每分钟250词计算) - 链接数量统计 2. **标签统计**: - 统计所有HTML标签的使用频率 - 以标签云形式展示,标签大小反映使用频率 3. **关键词高亮**: - 在正文内容中高亮显示指定关键词 - 使用`<mark>`标签实现高亮效果 - 关键词按长度降序排序,避免短关键词在长关键词内部匹配 4. **报告生成**: - 生成美观的分析报告 - 包含时间戳显示分析时间 ## 使用方法 1. 创建`BlogAnalyzer`实例,传入博客内容和关键词数组: ```php $analyzer = new BlogAnalyzer($blogContent, ['PHP', '性能优化']); ``` 2. 获取高亮后的内容: ```php $highlightedContent = $analyzer->highlightKeywords(); ``` 3. 生成分析报告: ```php $report = $analyzer->generateReport(); ``` 4. 在页面中显示内容和报告 ## 设计特点 - **响应式设计**:适配不同屏幕尺寸 - **视觉层次清晰**:使用卡片式设计展示不同类型的数据 - **交互体验**:关键词高亮帮助用户快速定位重要内容 - **性能优化**:使用高效的字符串处理函数和正则表达式 ## 技术细节 - 使用`strip_tags()`获取纯文本内容 - 使用`mb_strlen()`准确统计多字节字符 - 使用正则表达式统计标签和链接数量 - 使用CSS创建美观的标签云效果 - 关键词高亮避免影响HTML标签结构 这个实现可以直接集成到您的个人博客生成器项目中,提供详细的博客内容分析功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值