Christian Kruse: Regex: & in Links automatisch korrigieren

Beitrag lesen

你好 AllesMeins,

benutze da lieber einen richtigen[tm] Parser. Ein Regex kann nicht alle
Möglichkeiten abdecken. Ich habe das mal in C implementiert:

  
#define MOD_HTMLCOMMENT_QUOTE_SQ  0x1  
#define MOD_HTMLCOMMENT_QUOTE_DQ  0x2  
#define MOD_HTMLCOMMENT_QUOTE_AMP 0x4  
void mod_htmlcomment_append_plaintext(string_t *str,const u_char *content,int maskwhat) {  
  u_char buff[8],*ptr,*ptr1 = NULL,*val,*safe;  
  u_int32_t num;  
  size_t len;  
  
  for(ptr=(u_char *)content;*ptr;++ptr) {  
    /* ampersand, may be an entity */  
    if(*ptr == '&') {  
      if(maskwhat & MOD_HTMLCOMMENT_QUOTE_AMP) {  
        str_cstr_append(str,"&");  
        continue;  
      }  
  
      /* {{{ nummeric entity */  
      if(*(ptr+1) == '#') {  
        safe = ptr;  
  
        if(*(ptr+2) == 'x' || *(ptr+2) == 'X') {  
          for(ptr1=ptr+3;*ptr1 && isdigit(*ptr1);++ptr1);  
          if(*ptr1 != ';') {  
            /* hm, entity is fucked up */  
            str_cstr_append(str,"&");  
            ptr = safe;  
            continue;  
          }  
          num = strtol(ptr+3,(char **)&ptr,16);  
        }  
        else {  
          if(*ptr1 != ';') {  
            /* hm, entity is fucked up */  
            str_cstr_append(str,"&");  
            ptr = safe;  
            continue;  
          }  
  
          num = strtol(ptr+2,(char **)&ptr,10);  
        }  
  
        if(num == 0) {  
          /* entity is really fucked up */  
          str_cstr_append(str,"&");  
          ptr = safe;  
          continue;  
        }  
  
        if((len = unicode_to_utf8(num,buff,7)) == EINVAL) {  
          /* again, fucked up */  
          str_cstr_append(str,"&");  
          ptr = safe;  
          continue;  
        }  
  
        str_char_append(str,'&');  
        ptr = safe;  
      }  
      /* }}} */  
      /* {{{ named entity */  
      else {  
        for(safe=ptr++,val=ptr;*ptr && isalnum(*ptr);++ptr);  
        if(!isalnum(*ptr) && *ptr != ';') {  
          /* entity fucked up */  
          str_cstr_append(str,"&");  
          ptr = safe;  
          continue;  
        }  
  
        if(ptr-val == 0) {  
          str_cstr_append(str,"&");  
          ptr = safe;  
          continue;  
        }  
  
        val = strndup(val,ptr-val);  
        num = get_named_entity(val);  
        free(val);  
  
        if((len = unicode_to_utf8(num,buff,7)) == EINVAL) {  
          /* again, fucked up */  
          str_cstr_append(str,"&");  
          ptr = safe;  
          continue;  
        }  
  
        str_char_append(str,'&');  
        ptr = safe;  
      }  
      /* }}} */  
   }  
    else if(*ptr == '"') {  
      if(maskwhat & MOD_HTMLCOMMENT_QUOTE_DQ) str_cstr_append(str,""");  
      else str_char_append(str,'"');  
    }  
    else if(*ptr == '\'') {  
      if(maskwhat & MOD_HTMLCOMMENT_QUOTE_SQ) str_cstr_append(str,"'");  
      else str_char_append(str,'\'');  
    }  
    else if(*ptr == '<') str_cstr_append(str,"&lt;");  
    else if(*ptr == '>') str_cstr_append(str,"&gt;");  
    else str_char_append(str,*ptr);  
  }  
}  

Die Funktion macht noch einiges mehr als Entities reparieren, aber trotzdem
solltest du sie sehr leicht nach PHP übersetzen können.

再见,
 克里斯蒂安

--
Neuer alter Plasma-Bildschirm | Meine Schultüte
Die Summe zweier gerade Primzahlen ist immer eine Quadratzahl.
http://wwwtech.de/