开源html解析类无法正确解析段落之间的空格

2024-05-01

我正在使用一种开源方法,将 html 文本解析为 NSString。

生成的字符串在前几个段落之间有大量空格,但后续段落只有一行空格。这是输出的示例。

enter image description here Below is the method I'm calling. I've only changed two lines of the code. For stopCharacters and newLineAndWhitespaceCharacters, I removed /n from the characterset because when it was included, the entire text was one long paragraph.

- (NSString *)stringByConvertingHTMLToPlainText {

    // Pool
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

    // Character sets
    NSCharacterSet *stopCharacters = [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@"< \t\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
    NSCharacterSet *newLineAndWhitespaceCharacters = [NSCharacterSet characterSetWithCharactersInString:[NSString stringWithFormat:@" \t\r%C%C%C%C", 0x0085, 0x000C, 0x2028, 0x2029]];
    NSCharacterSet *tagNameCharacters = [NSCharacterSet characterSetWithCharactersInString:@"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"];

    // Scan and find all tags
    NSMutableString *result = [[NSMutableString alloc] initWithCapacity:self.length];
    NSScanner *scanner = [[NSScanner alloc] initWithString:self];
    [scanner setCharactersToBeSkipped:nil];
    [scanner setCaseSensitive:YES];
    NSString *str = nil, *tagName = nil;
    BOOL dontReplaceTagWithSpace = NO;
    do {

        // Scan up to the start of a tag or whitespace
        if ([scanner scanUpToCharactersFromSet:stopCharacters intoString:&str]) {
            [result appendString:str];
            str = nil; // reset
        }

        // Check if we've stopped at a tag/comment or whitespace
        if ([scanner scanString:@"<" intoString:NULL]) {

            // Stopped at a comment or tag
            if ([scanner scanString:@"!--" intoString:NULL]) {

                // Comment
                [scanner scanUpToString:@"-->" intoString:NULL];
                [scanner scanString:@"-->" intoString:NULL];

            } else {

                // Tag - remove and replace with space unless it's
                // a closing inline tag then dont replace with a space
                if ([scanner scanString:@"/" intoString:NULL]) {

                    // Closing tag - replace with space unless it's inline
                    tagName = nil; dontReplaceTagWithSpace = NO;
                    if ([scanner scanCharactersFromSet:tagNameCharacters intoString:&tagName]) {
                        tagName = [tagName lowercaseString];
                        dontReplaceTagWithSpace = ([tagName isEqualToString:@"a"] ||
                                                   [tagName isEqualToString:@"b"] ||
                                                   [tagName isEqualToString:@"i"] ||
                                                   [tagName isEqualToString:@"q"] ||
                                                   [tagName isEqualToString:@"span"] ||
                                                   [tagName isEqualToString:@"em"] ||
                                                   [tagName isEqualToString:@"strong"] ||
                                                   [tagName isEqualToString:@"cite"] ||
                                                   [tagName isEqualToString:@"abbr"] ||
                                                   [tagName isEqualToString:@"acronym"] ||
                                                   [tagName isEqualToString:@"label"]);
                    }

                    // Replace tag with string unless it was an inline
                    if (!dontReplaceTagWithSpace && result.length > 0 && ![scanner isAtEnd]) [result appendString:@" "];

                }

                // Scan past tag
                [scanner scanUpToString:@">" intoString:NULL];
                [scanner scanString:@">" intoString:NULL];

            }

        } else {

            // Stopped at whitespace - replace all whitespace and newlines with a space
            if ([scanner scanCharactersFromSet:newLineAndWhitespaceCharacters intoString:NULL]) {
                if (result.length > 0 && ![scanner isAtEnd]) [result appendString:@" "]; // Dont append space to beginning or end of result
            }

        }

    } while (![scanner isAtEnd]);

    // Cleanup
    [scanner release];

    // Decode HTML entities and return
    NSString *retString = [[result stringByDecodingHTMLEntities] retain];
    [result release];

    // Drain
    [pool drain];

    // Return
    return [retString autorelease];

}

EDIT:

这是字符串的 NSLog。我只粘贴了前几段

Mitt Romney spent the past six years running for president. After his loss to President Barack Obama, he'll have to chart a different course.  


 His initial plan: spend time with his family. He has five sons and 18 grandchildren, with a 19th on the way.  






 "I don't look at postelection to be a time of regrouping. Instead it's a time of forward focus," Romney told reporters aboard his plane Tuesday evening as he returned to Boston after the final campaign stop of his political career. "I have, of course, a family and life important to me, win or lose."  

 The most visible member of that family — wife Ann Romney — says neither she nor her husband will seek political office again.  

etc....

for (int j = 25; j< 50; j++) {
    char test =  [completeTrimmed characterAtIndex:([completeTrimmed rangeOfString:@"chart a different course."].location + j)];

        NSLog(@"%hhd", test);
    }

012-11-11 17:15:57.668 LMU_LAL_LAUNCHER[5431:c07] 32
2012-11-11 17:15:57.669 LMU_LAL_LAUNCHER[5431:c07] 32
2012-11-11 17:15:57.669 LMU_LAL_LAUNCHER[5431:c07] 10
2012-11-11 17:15:57.670 LMU_LAL_LAUNCHER[5431:c07] 32
2012-11-11 17:15:57.670 LMU_LAL_LAUNCHER[5431:c07] 32
2012-11-11 17:15:57.670 LMU_LAL_LAUNCHER[5431:c07] 10
2012-11-11 17:15:57.671 LMU_LAL_LAUNCHER[5431:c07] 32
2012-11-11 17:15:57.671 LMU_LAL_LAUNCHER[5431:c07] 32
2012-11-11 17:15:57.671 LMU_LAL_LAUNCHER[5431:c07] 10
2012-11-11 17:15:57.672 LMU_LAL_LAUNCHER[5431:c07] 32
2012-11-11 17:15:57.672 LMU_LAL_LAUNCHER[5431:c07] 72
2012-11-11 17:15:57.672 LMU_LAL_LAUNCHER[5431:c07] 105
2012-11-11 17:15:57.673 LMU_LAL_LAUNCHER[5431:c07] 115
2012-11-11 17:15:57.673 LMU_LAL_LAUNCHER[5431:c07] 32
2012-11-11 17:15:57.673 LMU_LAL_LAUNCHER[5431:c07] 105
2012-11-11 17:15:57.673 LMU_LAL_LAUNCHER[5431:c07] 110
2012-11-11 17:15:57.674 LMU_LAL_LAUNCHER[5431:c07] 105
2012-11-11 17:15:57.674 LMU_LAL_LAUNCHER[5431:c07] 116
2012-11-11 17:15:57.674 LMU_LAL_LAUNCHER[5431:c07] 105
2012-11-11 17:15:57.675 LMU_LAL_LAUNCHER[5431:c07] 97
2012-11-11 17:15:57.675 LMU_LAL_LAUNCHER[5431:c07] 108
2012-11-11 17:15:57.675 LMU_LAL_LAUNCHER[5431:c07] 32
2012-11-11 17:15:57.675 LMU_LAL_LAUNCHER[5431:c07] 112
2012-11-11 17:15:57.676 LMU_LAL_LAUNCHER[5431:c07] 108
2012-11-11 17:15:57.676 LMU_LAL_LAUNCHER[5431:c07] 97

检查一下这个,

  //Decode HTML entities and return
  NSString *retString = [result stringByDecodingHTMLEntities];
  [result release];

  //Drain
  [pool drain];

  retString = [[retString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] retain];

  //Return
  return [retString autorelease];   
}

如果上述方法不起作用,还可以尝试使用

completeTrimmed = [completeTrimmed stringByReplacingOccurrencesOfString:@"\n" withString:@""]; 

and

completeTrimmed = [completeTrimmed stringByReplacingOccurrencesOfString:@"\r" withString:@""];
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

开源html解析类无法正确解析段落之间的空格 的相关文章

  • 两者都实现了类。将使用两者之一

    我有一个项目 它具有使用 SocketRocket 的依赖项 通过 CocoaPods 安装 并从 HeapAnalytics 导入了静态库 显然 HeapAnalytics 库已经使用了 SocketRocket 编译时没有出现错误 但在
  • ViewWillAppear 没有被 UISplitViewController 调用

    背景和目标 我有一个基于 UISplitViewController 的 iPad 应用程序 到目前为止它支持 4 个方向 但现在我想将其锁定为仅横向 我变了shouldAutorotateToInterfaceOrientation左视图
  • Java 页面爬行和解析之 Crawler4j 与 Jsoup

    我想获取页面的内容并提取其中的特定部分 据我所知 此类任务至少有两种解决方案 爬虫4j https github com yasserg crawler4j and Jsoup http jsoup org 它们都能够检索页面的内容并提取其
  • 带有 Core Data 对象的动态 UITableView 高度

    过去几天我一直在试图解决一个谜团 即为什么我的批处理大小为 20 的 NSFetchedResultsController 总是在获取完成后立即错误 即加载到内存中 我的所有对象 从而导致请求需要约 20 秒 事实证明 这是因为在我的 he
  • Objective-C / C 给出枚举默认值

    我在某处读到过关于给枚举默认值的内容 如下所示 typedef enum MarketNavigationTypeNone 0 MarketNavigationTypeHeirachy 1 MarketNavigationTypeMarke
  • 使用超类初始化器初始化类

    我有两个类 一个是另一个的子类 比如说Animal and Dog 超类有一些初始化器 比如initAnimal 子类有一些初始化器 比如initDog 问题是 从编译器的角度来看 做类似的事情是完全合法的Dog adog Dog allo
  • 将维基百科中的表格加载到 R 中

    我正在尝试从以下 URL 将最高法院法官表加载到 R 中 https en wikipedia org wiki List of Justices of the Supreme Court of the United States http
  • 适用于 Objective-C / iPhone 的良好 HTTP 库? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 UPDATE 这个问题显然已经过时了 参见日期 我建议只使用现代 iOS7 功能 例如 NSURLSession 我想 这个问题是为了历史
  • 确定 NSView 是否绘制的正确方法

    有没有正确的方法来确定是否NSView实际上是否在当前视图层次结构中绘制 考虑以下情况 视图完全在屏幕外 不是强制性的 该视图不在视图层次结构的顶部 The isHidden and isHiddenOrHasHiddenAncestor不
  • 避免“在此块中强烈捕获自身可能会导致保留周期”消息

    每次我必须在块内使用全局变量或属性时 如下所示 self save if isItSaving NO self saveMyFile 我必须像这样重写 BOOL iis isItSaving id myself self self save
  • 使用 Storyboard 时获取 NSManagedObjectContext

    目标是获取当前的 NSManagedObjectContext 以便使用 Core Data 在 iOS 4 3 中 我将 UINavigationController 的委托设置为 AppDelegate 如下所示 在 AppDelega
  • 如何通过辅助功能 API 获取当前所选文本的全局屏幕坐标。

    我需要帮助来了解字典应用程序如何在任何应用程序上按 CMD CTRL D 时显示所选文本的以下弹出对话框 我想实施 我的可可应用程序具有相同的功能 我的应用程序将在后台运行 并显示有关所选文本的一些热键的建议 我已经实现了热键捕获 我只需要
  • 如何在 iOS 上捕获的视频中添加水印[重复]

    这个问题在这里已经有答案了 我想知道是否有人可以告诉我如何实现这一目标 如果一直在考虑几个解决方案 从捕获的视频创建单独的图像 然后将它们合并到每个图像中 然后创建一个新的 AVAsset 听起来有点复杂 您不觉得吗 合并2个视频 一个是透
  • 为什么我的 UIPickerView 崩溃了?

    当我使用 UIPickerView 加载视图时出现以下错误 由于未捕获的异常 NSInvalidArgumentException 而终止应用程序 原因 NSCFNumber isEqualToString 无法识别的选择器发送到实例 0x
  • 如何使用 MPMusicPlayerController 播放音乐?

    任何人都可以建议我如何在我的应用程序中使用 MPMusicPlayerController 播放音乐 任何人的帮助将不胜感激 谢谢你 莫尼什 创建一个MPMediaPickerController这样你就可以从 iPod 中选择一些音乐 然
  • iOS设备和iPhone模拟器内存​​组织的差异

    我正在尝试使用 Xcode 4 3 3 和 iPhone 5 1 模拟器开发一个应用程序 当我在模拟器上运行这个应用程序时 我没有收到任何警告 并且它运行得很好 但是 当我尝试在 iOS 设备上执行此操作时 我收到一条警告消息 收到内存警告
  • 停止 ARC 在空闲时释放对象

    我在 Objective C 中遇到内存管理问题 我一直在阅读高级内存管理编程指南 https developer apple com library mac documentation Cocoa Conceptual MemoryMgm
  • 有没有办法在 iOS 上获取相机流的亮度级别?

    我正在使用 iPhone iPad 摄像头获取视频流并在视频流上进行识别 但随着光照的变化 它会对鲁棒性产生负面影响 我已经在不同的光线下测试了不同的设置 并且可以让它工作 但尝试在运行时调整设置是我所需要的 我可以对每一帧进行简单的亮度检
  • 如何为整个 iOS 应用程序设置自定义字体而不指定大小

    我正在尝试在整个我的应用程序中应用自定义字体iOS app 我发现我可以使用 UILabel appearance setFont UIFont fontWithName Proxima Nova size 17 0 设置所有的默认字体和大
  • 如何检测按下的返回键并使用 UIKeyInput 协议对其进行响应?

    我有一个表视图 显示我希望用户能够编辑的列表 为了节省空间 并且让我的视图更容易看清 我创建了一个符合 UIKeyInput 协议的自定义工具栏 这样我就可以拉起键盘而无需使用任何文本字段 到目前为止 一切都很好 我有一个可变字符串正在处理

随机推荐

  • 无法启动 UI Automator 查看器

    我无法启动 UI Automator 查看器 任何人都可以帮助我吗 我怎样才能启动它 当我双击 uiautomatorviewer 一段时间时 黑色窗口打开但自动关闭 即使我在 Windows 路径变量中设置了变量 ANDROID HOME
  • 如何使用php从手机号码获取国家代码

    我正在从数据库中的数据库获取手机号码 我有超过 1000 个手机号码 我的数据库如下所示 mobilenumber 971525478965 919844005522 45712345678 我想遍历数据库中的每个数字并找到countryc
  • $lookup 多个级别而不使用 $unwind?

    我有以下收藏 场地集合 id ObjectId 5acdb8f65ea63a27c1facf86 name ASA College Manhattan Campus addedBy ObjectId 5ac8ba3582c2345af70d
  • 为什么仅当项目中使用 lambda 时,javaassist 在加载 Entitymanager 时才会抛出 invalid Constant type: 18

    在发布这个具体问题之前 我阅读了很多 QnA 大部分的javassist 无效常量 18问题已得到解答以升级javassist库 基于这些 QnA 我还将项目中的 lib 升级到了最新版本 它确实有效 但我不明白以下内容 需要有人帮助提供一
  • Robo 3T 错误:网络无法访问

    我正在尝试将 Robo 3T 连接到我的在线数据库 但它似乎不起作用 我可以用它连接到本地数据库 我尝试使用 MongoDB Compass 进行连接 详细信息和身份验证工作正常 我能够连接 但当我在 Robo 3T 中连接相同的细节时 它
  • 我想更改此代码以仅显示“确定”并删除取消按钮

    我想更改此代码以仅显示 确定 并删除取消按钮 Object contestacion5 JOptionPane showInputDialog null 5 Que describe mejor a la Norte a Examen Ti
  • .NET:对象头有什么用?

    在 NET 中 每个对象有 8 个字节的开销 4 个字节是指向对象类型的指针 另外 4 个字节 称为对象头 有何用途 注意 这个问题是在 2010 年提出的 并且是 32 位特定的 开销与位数相关 1 个指针大小用于 对象类型 方法表 1
  • 向元素添加类

    像这样 我有两个选项卡 所以当我单击其中一个选项卡时 它是活动的 逻辑的 现在我试图区分活动选项卡和非活动选项卡 但不是使用 css 属性 但我想向单击的选项卡添加特定的类 如下所示 tab1 addClass active 但是 没有什么
  • 如何避免 C 运行时 (crt*.o) 垃圾

    我有两个C源文件 foo1 c include
  • 条形图中的并排条形

    这是基于这个帖子 https stackoverflow com questions 26913954 make barplot in ggplot2 with summary statistics noredirect 1 comment
  • 如何更改matplotlib中填充线的线宽?

    有没有办法增加 matplotlib 中剖面线的宽度 例如 下面的代码通过指定linewidth仅改变边缘的宽度 我想更改用于填充的线的线宽 import matplotlib pyplot as plt import numpy as n
  • 在 WPF 中展开 TreeView 时显示“请稍候...”消息

    我的 TreeView 中有很多项目 而且项目也非常复杂 我不想使用虚拟化 展开 TreeView 有时需要花费大量时间 因此 是否有任何事件 例如 IsTreeViewExpanding 或类似的事件 我可以在其中显示 正在生成 Tree
  • 替换 lambda 表达式中的参数类型

    我正在尝试将 lambda 表达式中的参数类型从一种类型替换为另一种类型 我在 stackoverflow 上找到了其他答案 即this one https stackoverflow com questions 11159697 repl
  • 修改文本文件而不读入内存

    我试图找出一种修改文本文件 特别是删除特定行 的方法 而无需将文件的大部分读取到内存中或重写整个文件 这里讨论的是大于主内存约 15 50 Gigs 的文件 附 我正在使用Linux 你不会逃避创建一个新文件 所以就硬着头皮去做吧 使用gr
  • 在汇编中显示两位数? [复制]

    这个问题在这里已经有答案了 我对汇编编程完全陌生 在课堂作业的示例中 需要将两个数字相加并显示总和 我发现神秘的是当其是两位数时显示总和 这是我的代码 mov al num1 mov bl num2 add al bl add ax 303
  • 我应该为每个选项卡栏使用单独的 UINavigationController

    根据Apple https developer apple com library ios documentation WindowsViews Conceptual ViewControllerCatalog Chapters Combi
  • Node.js、EventEmitter 为什么使用它

    我有一个问题events EventEmitter在 Node js 中 为什么使用它 示例1和示例2有什么区别 我发现它们是相同的 是吗 什么时候可以实际使用它 let events require events let util req
  • 在 Libgdx 中实现简单运动模糊的意外结果

    在所附的两张图片中 libgdx 的桌面屏幕截图按预期运行 不幸的是 我的 Galaxy Nexus 的屏幕截图与预期不符 我正在尝试创建一个简单的运动模糊或轨迹效果 Rendering as I expected on my deskto
  • C++:输入和输出流运算符:结合性

    输入 输出流运算符理论上的结合性 左到右 例如 根据这个 圣玛丽大学网站 http cs smu ca porter csc ref cpp operators html 输入 输出流运算符结合性实践 include
  • 开源html解析类无法正确解析段落之间的空格

    我正在使用一种开源方法 将 html 文本解析为 NSString 生成的字符串在前几个段落之间有大量空格 但后续段落只有一行空格 这是输出的示例 Below is the method I m calling I ve only chan