`
touchmm
  • 浏览: 1037743 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

试了一把PCRE

阅读更多

虽然我在C++里用正则表达式已经有一些年头了,不过一直都是用的boost里那个库。坦白说,不是很好用。虽然我很早就知道PCRE,但一直都以为这是一个为PHP开发的库。实在是火星人啊。囧

前两天在推土上提起这事时,火炬向我推荐说PCRE比boost里那个正则库好用,于是试了一下,结果可耻滴发现BCB自带了PCRE,只不过没有在文档里提到罢了。

不 过PCRE是一个C语言的库,用起来不够方便。虽然也有PCRE++这种C++封装的版本,但是只提供了GNU编译配置,移植到BCB里估计比较麻烦,因 为我用到的功能也不多,就自己做了个简单的封装,用了一些VCL的AnsiString/StringList之类。用起来方便不少。

#include <pcre.h>

class TPCRE
{
private:
AnsiString FPattern;
pcre * FRE;
TStrings * FMatches;

public:
__fastcall TPCRE(AnsiString aPattern="");
__fastcall ~TPCRE();

void __fastcall compile(AnsiString aPattern="");
int __fastcall exec(AnsiString aStr); // return matched count
AnsiString __fastcall repeat_replace(AnsiString aStr, AnsiString aRepStr="");

__property TStrings * Matches = { read = FMatches };
};

__fastcall TPCRE::TPCRE(AnsiString aPattern)
: FRE(NULL), FMatches(new TStringList())
{
FPattern = aPattern;
if ( FPattern != "" )
compile();
}

__fastcall TPCRE::~TPCRE()
{
if (FRE)
free(FRE);
delete FMatches;
}

void __fastcall TPCRE::compile(AnsiString aPattern)
{
if ( aPattern != "" )
FPattern = aPattern;
const char * error;
int erroffset;
if (FRE)
free(FRE);
FRE = pcre_compile(FPattern.c_str(), 0, &error, &erroffset, NULL);
// if ( FRE == NULL )
// PCRE compilation failed at offset %d: %s, erroffset, error
}

int __fastcall TPCRE::exec(AnsiString aStr)
{
if (!FRE)
throw Exception("No pattern or have not be compiled!");
const int OVECCOUNT = 30;
int ovector[OVECCOUNT];
int rc = pcre_exec(FRE, NULL, aStr.c_str(), aStr.Length(), 0, ovector, OVECCOUNT);
if (rc < 0) {
if (rc == PCRE_ERROR_NOMATCH)
throw Exception("Sorry, no match ...");
else
throw Exception(AnsiString("Matching error ") + IntToStr(rc));
}
// OK, has matched ...
FMatches->Clear();
for (int i = 0; i < rc; i++)
FMatches->Add(aStr.SubString(
ovector[2*i]+1, ovector[2*i+1]-ovector[2*i]));
return rc;
}

AnsiString __fastcall TPCRE::repeat_replace(AnsiString aStr, AnsiString aRepStr)
{
if (!FRE)
throw Exception("No pattern or have not be compiled!");
const int OVECCOUNT = 30;
int ovector[OVECCOUNT];
int rc=1;
char *p = aStr.c_str();
int n = 1;
int len = aStr.Length();
AnsiString s="";
while (rc>0) {
rc = pcre_exec(FRE, NULL, p, len, 0, ovector, OVECCOUNT);
if (rc < 0) {
if (rc == PCRE_ERROR_NOMATCH) {
if (s=="")
s = aStr;
else
s += aStr.SubString(n,aStr.Length()-n+1);
break;
}
else
throw Exception(AnsiString("Matching error ") + IntToStr(rc));
}
// OK, has matched ...
s += aStr.SubString(n,ovector[0])+aRepStr;
n += ovector[1];
p = aStr.c_str()+n-1;
len = aStr.Length()-n+1;
}
return s;
}

用法很简单,这是一段示例代码,可以把HTML转换成TXT:

// 输入:const char *s
// 输出:AnsiString sResult
std::auto_ptr<TPCRE> re(new TPCRE("(?ims)<title>([^<]*)"));
AnsiString sResult;
if (re->exec(s)>1)
sResult = re->Matches->Strings[1].Trim();
re->compile("(?ims)<body[^>]*>(.*)");
if (re->exec(s)>1) {
AnsiString str = re->Matches->Strings[1].Trim();
str = StringReplace(str,"\r","",TReplaceFlags()<<rfReplaceAll);
str = StringReplace(str,"\n","",TReplaceFlags()<<rfReplaceAll);
str = StringReplace(str,"&nbsp;"," ",TReplaceFlags()<<rfReplaceAll);
// replace <br /> to \r\n
re->compile("(?i)<br\s*/?>");
str = re->repeat_replace(str,"\r\n");
// remove <script...>...</script>
re->compile("(?ims)<script[^>]*>.*</script>");
str = re->repeat_replace(str);
// remove <!-- ... -->
re->compile("(?ims)<!--.*-->");
str = re->repeat_replace(str);
// remove <...>
re->compile("(?ims)<[^>]*>");
str = re->repeat_replace(str);
sResult += str;
}

主要就是取出title部分和body部分,然后将body部分的回车全部去掉,&nbsp;替换成空格,br换成回车,脚本和注释去掉,最后去掉所有HTML的标记。

分享到:
评论

相关推荐

    pcre-8.39.tar.gz

    标题 "pcre-8.39.tar.gz" 暗示了这是一个包含PCRE(Perl Compatible Regular Expressions)库的版本8.39的源代码压缩包,它以tar.gz格式封装。这种格式通常用于在Linux和Unix-like系统中分发软件。PCRE是一个开源库...

    pcre2-10.10.tar.gz

    标题 "pcre2-10.10.tar.gz" 指的是一个名为"Pcre2"的库软件的源代码包,版本号为10.10,它被打包成一个`.tar.gz`格式的压缩文件。`.tar.gz`是Linux系统中常见的归档和压缩格式,通常用于在互联网上分发开源软件项目...

    nginx 端口映射

    Nginx 作为一个轻量级的 Web 服务器软件,它具有许多重要的作用之一是实现 IP 端口映射。通过 Nginx,我们可以将外部的 HTTP 请求转发到内部的服务器上,从而实现负载均衡、反向代理、缓存等功能。 在本文中,我们...

    nginx安装及其配置详细教程.docx

    1. 把 nginx 源码包上传到 linux 系统上 2. 解压到 /usr/local 下面:# tar -xvf nginx-1.14.0.tar.gz -C /usr/local 3. 使用 configure 命令创建一个 makeFile 文件,执行下面的命令的时候,一定要进入到 nginx-...

    Linux上搭建nginx,及简单配置

    在上家公司都是运维安装nginx,到新公司后代码开发完成部署测试服务器要求自己装nginx,研究了好久安装好之后,到正式上线还要自己安装,索性把安装步骤自己记载下来(好大一部分都是在网站找的)。  一,安装  ...

    Linux环境下nginx安装配置.docx

    2. 权重:把请求更多的分配到高配置的后端服务器上,默认每个服务器的权重都是 1。 3. IP 哈希:同一客户端的 Web 请求被分发到同一个后端服务器进行处理,使用该策略可以有效的避免用户 Session 失效的问题。 4. ...

    搭建FastDFS(保姆级教程).pdf

    * 安装依赖项:yum -y install gcc-c++、yum -y install libevent、yum install -y pcre pcre-devel、yum install -y zlib zlib-devel、yum install -y openssl openssl-devel * 编译和安装libfastcommon:tar -zxvf...

    php代码-在线 php 正则表达式在线测试,php正则测试,在线php正则匹配

    这将把字符串按空格分隔成数组。 在线PHP正则表达式测试工具则提供了一个方便的环境,让用户可以在无需搭建本地环境的情况下测试和调试正则表达式。这些工具通常有一个输入框供用户输入PHP代码,另一个输入框输入待...

    服务灰度发布方案.docx

    AB test 就是一种灰度发布方式,让一部分用户继续用 A,一部分用户开始用 B,如果用户对 B 没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到 B 上面来。灰度发布可以保证整体系统的稳定,在初始灰度的时候就...

    nginx资源包.zip

    这将会把Nginx二进制文件安装到指定的`--prefix`目录下。 8. **启动与管理Nginx**: 安装完成后,可以使用`/usr/local/nginx/sbin/nginx`启动Nginx,`nginx -s reload`来重新加载配置,`nginx -s stop`或`nginx -s...

    正则表达式的烦恼

    总结来说,正则表达式是一把双刃剑,既强大又复杂。理解其基本概念和语法,掌握常见问题的解决方案,以及合理利用工具,都能帮助我们更好地应对“正则表达式的烦恼”,从而在编程实践中发挥它的最大效用。通过持续...

    windows下androidNDK环境配置

    然后开始选择安装这些包吧,点skip,把它变成数字版本格式,要确保Bin项变成叉号,而Src项是源码,这个就没必要选了。 9. 测试Cygwin 运行Cygwin,在弹出的命令行窗口输入:cygcheck -c cygwin命令,会打印出当前...

    nginx-linux-1.24.0.tar.gz

    这将把Nginx安装到`/usr/local/nginx`目录,并包含HTTPS支持和状态模块。配置成功后,可以进行编译和安装: ```bash make sudo make install ``` 安装完成后,Nginx的可执行文件默认位于`/usr/local/nginx/sbin`...

    Linux中用yum在本地装软件.pdf

    2. 把所有的RPM包都放到Nginx的一个网页目录下,保证能正常访问,并配置。 3. 挂载光盘到/mnt/或将ISO文件挂载到该目录下。 4. copy所有的RPM包到/usr/local/nginx/html/CentOS下。 5. 配置Nginx,使用户能访问所有...

    Nginx编译所需文件

    - **依赖库**:Nginx编译需要一些基础的系统库,例如pcre(Perl Compatible Regular Expressions)、zlib(数据压缩库)和openssl(加密库)。确保这些库已安装并更新至最新版本。 2. **交叉编译** - **交叉编译...

    nginx-1.6.2.tar 源码 需要编译

    默认情况下,`make install` 将把 Nginx 配置文件安装到 `/usr/local/nginx/conf/nginx.conf`。打开这个文件,根据你的需求进行修改,例如设置监听端口、日志路径、服务器块等。 **6. 初始化系统服务** 为了让 ...

    nginx-sticky 不报错版

    4. **编译和安装**:执行 `make` 和 `make install` 来编译和安装 Nginx,这将把带有 sticky 模块的 Nginx 安装到系统指定的位置。 5. **配置 Nginx 配置文件**:编辑 Nginx 的配置文件,如 `nginx.conf`,在负载...

    PHP正则表达式替换站点关键字链接后空白的解决方法

    1. 定义替换规则:在函数ReplaceKeyword中,首先创建了一个映射数组$linkMap,该数组定义了替换的规则,即把文章中的某些关键词链接化。 2. 替换原有链接:通过foreach循环遍历$linkMap数组,并用preg_replace函数...

    nginx-1.25.1(ngx-http-proxy-connect-module插件)windows版本

    确保你的环境中已经安装了必要的依赖库,如pcre、openssl等。在编译时,需要通过合适的配置选项添加ngx_http_proxy_connect_module,例如: ``` ./configure --with-...

Global site tag (gtag.js) - Google Analytics