⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcrecpp.cc

📁 PHP v6.0 For Linux 运行环境:Win9X/ WinME/ WinNT/ Win2K/ WinXP
💻 CC
📖 第 1 页 / 共 2 页
字号:
// Copyright (c) 2005, Google Inc.// All rights reserved.//// Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:////     * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.//     * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following disclaimer// in the documentation and/or other materials provided with the// distribution.//     * Neither the name of Google Inc. nor the names of its// contributors may be used to endorse or promote products derived from// this software without specific prior written permission.//// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.//// Author: Sanjay Ghemawat#include <stdlib.h>#include <stdio.h>#include <ctype.h>#include <limits.h>      /* for SHRT_MIN, USHRT_MAX, etc */#include <assert.h>#include <errno.h>#include <string>#include <algorithm>#include "config.h"// We need this to compile the proper dll on windows/msys.  This is copied// from pcre_internal.h.  It would probably be better just to include that.#define PCRE_DEFINITION  /* Win32 __declspec(export) trigger for .dll */#include "pcre.h"#include "pcre_stringpiece.h"#include "pcrecpp.h"namespace pcrecpp {// Maximum number of args we can setstatic const int kMaxArgs = 16;static const int kVecSize = (1 + kMaxArgs) * 3;  // results + PCRE workspace// Special object that stands-in for no argumentArg no_arg((void*)NULL);// If a regular expression has no error, its error_ field points herestatic const string empty_string;// If the user doesn't ask for any options, we just use this onestatic RE_Options default_options;void RE::Init(const char* pat, const RE_Options* options) {  pattern_ = pat;  if (options == NULL) {    options_ = default_options;  } else {    options_ = *options;  }  error_ = &empty_string;  re_full_ = NULL;  re_partial_ = NULL;  re_partial_ = Compile(UNANCHORED);  if (re_partial_ != NULL) {    // Check for complicated patterns.  The following change is    // conservative in that it may treat some "simple" patterns    // as "complex" (e.g., if the vertical bar is in a character    // class or is escaped).  But it seems good enough.    if (strchr(pat, '|') == NULL) {      // Simple pattern: we can use position-based checks to perform      // fully anchored matches      re_full_ = re_partial_;    } else {      // We need a special pattern for anchored matches      re_full_ = Compile(ANCHOR_BOTH);    }  }}RE::~RE() {  if (re_full_ != NULL && re_full_ != re_partial_) (*pcre_free)(re_full_);  if (re_partial_ != NULL)                         (*pcre_free)(re_partial_);  if (error_ != &empty_string)                     delete error_;}pcre* RE::Compile(Anchor anchor) {  // First, convert RE_Options into pcre options  int pcre_options = 0;  pcre_options = options_.all_options();  // Special treatment for anchoring.  This is needed because at  // runtime pcre only provides an option for anchoring at the  // beginning of a string (unless you use offset).  //  // There are three types of anchoring we want:  //    UNANCHORED      Compile the original pattern, and use  //                    a pcre unanchored match.  //    ANCHOR_START    Compile the original pattern, and use  //                    a pcre anchored match.  //    ANCHOR_BOTH     Tack a "\z" to the end of the original pattern  //                    and use a pcre anchored match.  const char* compile_error;  int eoffset;  pcre* re;  if (anchor != ANCHOR_BOTH) {    re = pcre_compile(pattern_.c_str(), pcre_options,                      &compile_error, &eoffset, NULL);  } else {    // Tack a '\z' at the end of RE.  Parenthesize it first so that    // the '\z' applies to all top-level alternatives in the regexp.    string wrapped = "(?:";  // A non-counting grouping operator    wrapped += pattern_;    wrapped += ")\\z";    re = pcre_compile(wrapped.c_str(), pcre_options,                      &compile_error, &eoffset, NULL);  }  if (re == NULL) {    if (error_ == &empty_string) error_ = new string(compile_error);  }  return re;}/***** Matching interfaces *****/bool RE::FullMatch(const StringPiece& text,                   const Arg& ptr1,                   const Arg& ptr2,                   const Arg& ptr3,                   const Arg& ptr4,                   const Arg& ptr5,                   const Arg& ptr6,                   const Arg& ptr7,                   const Arg& ptr8,                   const Arg& ptr9,                   const Arg& ptr10,                   const Arg& ptr11,                   const Arg& ptr12,                   const Arg& ptr13,                   const Arg& ptr14,                   const Arg& ptr15,                   const Arg& ptr16) const {  const Arg* args[kMaxArgs];  int n = 0;  if (&ptr1  == &no_arg) goto done; args[n++] = &ptr1;  if (&ptr2  == &no_arg) goto done; args[n++] = &ptr2;  if (&ptr3  == &no_arg) goto done; args[n++] = &ptr3;  if (&ptr4  == &no_arg) goto done; args[n++] = &ptr4;  if (&ptr5  == &no_arg) goto done; args[n++] = &ptr5;  if (&ptr6  == &no_arg) goto done; args[n++] = &ptr6;  if (&ptr7  == &no_arg) goto done; args[n++] = &ptr7;  if (&ptr8  == &no_arg) goto done; args[n++] = &ptr8;  if (&ptr9  == &no_arg) goto done; args[n++] = &ptr9;  if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10;  if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11;  if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12;  if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13;  if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14;  if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15;  if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done:  int consumed;  int vec[kVecSize];  return DoMatchImpl(text, ANCHOR_BOTH, &consumed, args, n, vec, kVecSize);}bool RE::PartialMatch(const StringPiece& text,                      const Arg& ptr1,                      const Arg& ptr2,                      const Arg& ptr3,                      const Arg& ptr4,                      const Arg& ptr5,                      const Arg& ptr6,                      const Arg& ptr7,                      const Arg& ptr8,                      const Arg& ptr9,                      const Arg& ptr10,                      const Arg& ptr11,                      const Arg& ptr12,                      const Arg& ptr13,                      const Arg& ptr14,                      const Arg& ptr15,                      const Arg& ptr16) const {  const Arg* args[kMaxArgs];  int n = 0;  if (&ptr1  == &no_arg) goto done; args[n++] = &ptr1;  if (&ptr2  == &no_arg) goto done; args[n++] = &ptr2;  if (&ptr3  == &no_arg) goto done; args[n++] = &ptr3;  if (&ptr4  == &no_arg) goto done; args[n++] = &ptr4;  if (&ptr5  == &no_arg) goto done; args[n++] = &ptr5;  if (&ptr6  == &no_arg) goto done; args[n++] = &ptr6;  if (&ptr7  == &no_arg) goto done; args[n++] = &ptr7;  if (&ptr8  == &no_arg) goto done; args[n++] = &ptr8;  if (&ptr9  == &no_arg) goto done; args[n++] = &ptr9;  if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10;  if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11;  if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12;  if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13;  if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14;  if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15;  if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done:  int consumed;  int vec[kVecSize];  return DoMatchImpl(text, UNANCHORED, &consumed, args, n, vec, kVecSize);}bool RE::Consume(StringPiece* input,                 const Arg& ptr1,                 const Arg& ptr2,                 const Arg& ptr3,                 const Arg& ptr4,                 const Arg& ptr5,                 const Arg& ptr6,                 const Arg& ptr7,                 const Arg& ptr8,                 const Arg& ptr9,                 const Arg& ptr10,                 const Arg& ptr11,                 const Arg& ptr12,                 const Arg& ptr13,                 const Arg& ptr14,                 const Arg& ptr15,                 const Arg& ptr16) const {  const Arg* args[kMaxArgs];  int n = 0;  if (&ptr1  == &no_arg) goto done; args[n++] = &ptr1;  if (&ptr2  == &no_arg) goto done; args[n++] = &ptr2;  if (&ptr3  == &no_arg) goto done; args[n++] = &ptr3;  if (&ptr4  == &no_arg) goto done; args[n++] = &ptr4;  if (&ptr5  == &no_arg) goto done; args[n++] = &ptr5;  if (&ptr6  == &no_arg) goto done; args[n++] = &ptr6;  if (&ptr7  == &no_arg) goto done; args[n++] = &ptr7;  if (&ptr8  == &no_arg) goto done; args[n++] = &ptr8;  if (&ptr9  == &no_arg) goto done; args[n++] = &ptr9;  if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10;  if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11;  if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12;  if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13;  if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14;  if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15;  if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done:  int consumed;  int vec[kVecSize];  if (DoMatchImpl(*input, ANCHOR_START, &consumed,                  args, n, vec, kVecSize)) {    input->remove_prefix(consumed);    return true;  } else {    return false;  }}bool RE::FindAndConsume(StringPiece* input,                        const Arg& ptr1,                        const Arg& ptr2,                        const Arg& ptr3,                        const Arg& ptr4,                        const Arg& ptr5,                        const Arg& ptr6,                        const Arg& ptr7,                        const Arg& ptr8,                        const Arg& ptr9,                        const Arg& ptr10,                        const Arg& ptr11,                        const Arg& ptr12,                        const Arg& ptr13,                        const Arg& ptr14,                        const Arg& ptr15,                        const Arg& ptr16) const {  const Arg* args[kMaxArgs];  int n = 0;  if (&ptr1  == &no_arg) goto done; args[n++] = &ptr1;  if (&ptr2  == &no_arg) goto done; args[n++] = &ptr2;  if (&ptr3  == &no_arg) goto done; args[n++] = &ptr3;  if (&ptr4  == &no_arg) goto done; args[n++] = &ptr4;  if (&ptr5  == &no_arg) goto done; args[n++] = &ptr5;  if (&ptr6  == &no_arg) goto done; args[n++] = &ptr6;  if (&ptr7  == &no_arg) goto done; args[n++] = &ptr7;  if (&ptr8  == &no_arg) goto done; args[n++] = &ptr8;  if (&ptr9  == &no_arg) goto done; args[n++] = &ptr9;  if (&ptr10 == &no_arg) goto done; args[n++] = &ptr10;  if (&ptr11 == &no_arg) goto done; args[n++] = &ptr11;  if (&ptr12 == &no_arg) goto done; args[n++] = &ptr12;  if (&ptr13 == &no_arg) goto done; args[n++] = &ptr13;  if (&ptr14 == &no_arg) goto done; args[n++] = &ptr14;  if (&ptr15 == &no_arg) goto done; args[n++] = &ptr15;  if (&ptr16 == &no_arg) goto done; args[n++] = &ptr16; done:  int consumed;  int vec[kVecSize];  if (DoMatchImpl(*input, UNANCHORED, &consumed,                  args, n, vec, kVecSize)) {    input->remove_prefix(consumed);    return true;  } else {    return false;  }}bool RE::Replace(const StringPiece& rewrite,                 string *str) const {  int vec[kVecSize];  int matches = TryMatch(*str, 0, UNANCHORED, vec, kVecSize);  if (matches == 0)    return false;  string s;  if (!Rewrite(&s, rewrite, *str, vec, matches))    return false;  assert(vec[0] >= 0);  assert(vec[1] >= 0);  str->replace(vec[0], vec[1] - vec[0], s);  return true;}int RE::GlobalReplace(const StringPiece& rewrite,                      string *str) const {  int count = 0;  int vec[kVecSize];  string out;  int start = 0;  int lastend = -1;  for (; start <= static_cast<int>(str->length()); count++) {    int matches = TryMatch(*str, start, UNANCHORED, vec, kVecSize);    if (matches <= 0)      break;    int matchstart = vec[0], matchend = vec[1];    assert(matchstart >= start);    assert(matchend >= matchstart);    if (matchstart == matchend && matchstart == lastend) {      // advance one character if we matched an empty string at the same      // place as the last match occurred      if (start < static_cast<int>(str->length()))        out.push_back((*str)[start]);      start++;    } else {      out.append(*str, start, matchstart - start);      Rewrite(&out, rewrite, *str, vec, matches);      start = matchend;      lastend = matchend;      count++;    }  }  if (count == 0)    return 0;  if (start < static_cast<int>(str->length()))    out.append(*str, start, str->length() - start);  swap(out, *str);  return count;}bool RE::Extract(const StringPiece& rewrite,                 const StringPiece& text,                 string *out) const {  int vec[kVecSize];  int matches = TryMatch(text, 0, UNANCHORED, vec, kVecSize);  if (matches == 0)    return false;  out->erase();  return Rewrite(out, rewrite, text, vec, matches);}/***** Actual matching and rewriting code *****/int RE::TryMatch(const StringPiece& text,                 int startpos,                 Anchor anchor,                 int *vec,                 int vecsize) const {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -