ios - development - gsx api apple



Remover tags HTML de um NSString no iPhone (15)

A seguir está a resposta aceita, mas em vez de categoria, é um método auxiliar simples com uma cadeia passada para ela. (obrigado m.kocikowski)

-(NSString *) stringByStrippingHTML:(NSString*)originalString {
    NSRange r;
    NSString *s = [originalString copy];
    while ((r = [s rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
        s = [s stringByReplacingCharactersInRange:r withString:@""];
    return s;
}

https://ffff65535.com

Existem algumas maneiras diferentes de remover HTML tags de um NSString em Cocoa .

Uma maneira é renderizar a string em um NSAttributedString e depois pegar o texto renderizado.

Outra maneira é usar NSXMLDocument's método - NSXMLDocument's objectByApplyingXSLTString para aplicar uma transformação XSLT que o faça.

Infelizmente, o iPhone não suporta NSAttributedString ou NSXMLDocument . Há muitos casos de borda e documentos HTML malformados para que eu me sinta confortável usando o regex ou o NSScanner . Alguém tem uma solução para isso?

Uma sugestão foi simplesmente procurar abrir e fechar caracteres de tag, esse método não funcionará, exceto em casos muito triviais.

Por exemplo, esses casos (do capítulo Perl Cookbook sobre o mesmo assunto) quebrariam esse método:

<IMG SRC = "foo.gif" ALT = "A > B">

<!-- <A comment> -->

<script>if (a<b && a>c)</script>

<![INCLUDE CDATA [ >>>>>>>>>>>> ]]>

Aqui está a versão rápida:

func stripHTMLFromString(string: String) -> String {
  var copy = string
  while let range = copy.rangeOfString("<[^>]+>", options: .RegularExpressionSearch) {
    copy = copy.stringByReplacingCharactersInRange(range, withString: "")
  }
  copy = copy.stringByReplacingOccurrencesOfString("&nbsp;", withString: " ")
  copy = copy.stringByReplacingOccurrencesOfString("&amp;", withString: "&")
  return copy
}

Aqui está uma solução mais eficiente que a resposta aceita:

- (NSString*)hp_stringByRemovingTags
{
    static NSRegularExpression *regex = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        regex = [NSRegularExpression regularExpressionWithPattern:@"<[^>]+>" options:kNilOptions error:nil];
    });

    // Use reverse enumerator to delete characters without affecting indexes
    NSArray *matches =[regex matchesInString:self options:kNilOptions range:NSMakeRange(0, self.length)];
    NSEnumerator *enumerator = matches.reverseObjectEnumerator;

    NSTextCheckingResult *match = nil;
    NSMutableString *modifiedString = self.mutableCopy;
    while ((match = [enumerator nextObject]))
    {
        [modifiedString deleteCharactersInRange:match.range];
    }
    return modifiedString;
}

A categoria NSString acima usa uma expressão regular para encontrar todas as tags correspondentes, faz uma cópia da string original e, finalmente, remove todas as tags no lugar, iterando-as na ordem inversa. É mais eficiente porque:

  • A expressão regular é inicializada apenas uma vez.
  • Uma cópia única da string original é usada.

Isso NSScanner bem o suficiente para mim, mas uma solução usando o NSScanner pode ser mais eficiente.

Como a resposta aceita, esta solução não resolve todos os casos de fronteira solicitados pelo @lfalin. Isso exigiria uma análise muito mais cara, que o caso de uso médio provavelmente não precisa.


Dê uma olhada no NSXMLParser. É um analisador do estilo SAX. Você deve ser capaz de usá-lo para detectar tags ou outros elementos indesejados no documento XML e ignorá-los, capturando apenas texto puro.


Esta categoria NSString usa o NSXMLParser para remover com precisão qualquer tag HTML de um NSString . Este é um único arquivo .m e .h que pode ser incluído em seu projeto com facilidade.

https://gist.github.com/leighmcculloch/1202238

Você tira o html fazendo o seguinte:

Importe o cabeçalho:

#import "NSString_stripHtml.h"

E então chame stripHtml:

NSString* mystring = @"<b>Hello</b> World!!";
NSString* stripped = [mystring stripHtml];
// stripped will be = Hello World!!

Isso também funciona com HTML malformado que tecnicamente não é XML .


Estendendo isso mais das respostas de m.kocikowski e Dan J com mais explicações para iniciantes

1 # Primeiro você tem que criar categorias objective-c-categories para tornar o código utilizável em qualquer classe.

.h

@interface NSString (NAME_OF_CATEGORY)

- (NSString *)stringByStrippingHTML;

@end

.m

@implementation NSString (NAME_OF_CATEGORY)

- (NSString *)stringByStrippingHTML
{
NSMutableString *outString;
NSString *inputString = self;

if (inputString)
{
    outString = [[NSMutableString alloc] initWithString:inputString];

    if ([inputString length] > 0)
    {
        NSRange r;

        while ((r = [outString rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
        {
            [outString deleteCharactersInRange:r];
        }
    }
}

return outString;
}

@end

2 # Depois, basta importar o arquivo .h da classe de categoria que você acabou de criar, por exemplo:

#import "NSString+NAME_OF_CATEGORY.h"

3 # Chamando o método.

NSString* sub = [result stringByStrippingHTML];
NSLog(@"%@", sub);

Resultado é NSString eu quero tirar as tags de.


Eu imagino que o caminho mais seguro seria simplesmente analisar <> s, não? Faça um loop por toda a string e copie qualquer coisa que não esteja entre <s para uma nova string.


Eu tenho seguindo a resposta aceita por m.kocikowski e modificado é um pouco para fazer uso de um autoreleasepool para limpar todas as seqüências de caracteres temporárias que são criadas por stringByReplacingCharactersInRange

No comentário para este método, ele afirma, / * Substitua caracteres no intervalo pela string especificada, retornando uma nova string. * /

Portanto, dependendo do tamanho do seu XML, você pode estar criando uma enorme pilha de novas cadeias de autorelease que não são limpas até o final do próximo @autoreleasepool. Se você não tiver certeza de quando isso pode acontecer ou se uma ação do usuário pode acionar várias chamadas repetidamente para esse método antes, você pode apenas agrupar isso em um @autoreleasepool. Estes podem até ser aninhados e usados ​​dentro de loops sempre que possível.

A referência da Apple em @autoreleasepool declara isso ... "Se você escrever um loop que cria muitos objetos temporários. Você pode usar um bloco de pool autorelease dentro do loop para descartar esses objetos antes da próxima iteração. Usando um bloco de pool de autorelease no loop ajuda a reduzir o consumo máximo de memória do aplicativo. " Eu não usei no loop, mas pelo menos esse método limpa depois de si mesmo agora.

- (NSString *) stringByStrippingHTML {
    NSString *retVal;
    @autoreleasepool {
        NSRange r;
        NSString *s = [[self copy] autorelease];
        while ((r = [s rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound) {
            s = [s stringByReplacingCharactersInRange:r withString:@""];
        }
        retVal = [s copy];
    } 
    // pool is drained, release s and all temp 
    // strings created by stringByReplacingCharactersInRange
    return retVal;
}

Se você deseja obter o conteúdo sem as tags html da página da Web (documento HTML), use esse código dentro do método delegado UIWebViewDidfinishLoading .

  NSString *myText = [webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.textContent"];

Se você estiver disposto a usar o framework Three20 , ele terá uma categoria no NSString que adiciona o método stringByRemovingHTMLTags. Veja NSStringAdditions.h no subprojeto Three20Core.


Uma resposta atualizada para @ m.kocikowski que funciona em versões recentes do iOS.

-(NSString *) stringByStrippingHTMLFromString:(NSString *)str {
NSRange range;
while ((range = [str rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
    str = [str stringByReplacingCharactersInRange:range withString:@""];
return str;

}


Uma solução rápida e "suja" (remove tudo entre <e>), funciona com iOS> = 3.2:

-(NSString *) stringByStrippingHTML {
  NSRange r;
  NSString *s = [[self copy] autorelease];
  while ((r = [s rangeOfString:@"<[^>]+>" options:NSRegularExpressionSearch]).location != NSNotFound)
    s = [s stringByReplacingCharactersInRange:r withString:@""];
  return s;
}

Eu tenho isso declarado como uma categoria de NSString.


usa isto

NSString *myregex = @"<[^>]*>"; //regex to remove any html tag

NSString *htmlString = @"<html>bla bla</html>";
NSString *stringWithoutHTML = [hstmString stringByReplacingOccurrencesOfRegex:myregex withString:@""];

não se esqueça de incluir isso no seu código: #import "RegexKitLite.h" aqui está o link para baixar essa API: http://regexkit.sourceforge.net/#Downloads


#import "RegexKitLite.h"

string text = [html stringByReplacingOccurrencesOfRegex:@"<[^>]+>" withString:@""]

UITextView *textview= [[UITextView alloc]initWithFrame:CGRectMake(10, 130, 250, 170)];
NSString *str = @"This is <font color='red'>simple</font>";
[textview setValue:str forKey:@"contentToHTMLString"];
textview.textAlignment = NSTextAlignmentLeft;
textview.editable = NO;
textview.font = [UIFont fontWithName:@"vardana" size:20.0];
[UIView addSubview:textview];

funciona bem para mim





nsstring