如何在不创建格式错误的HTML标签的情况下分解字符串?

詹汉布·马利克

我在做什么

  • 在NodeJS中,我将使用MustacheJS(使用JSON对象数组中的数据)创建电子邮件模板。
  • 模板中包含的文本/消息可以包含文本以及基本的html标签(例如b pa)。
  • 由于篇幅所限,我只需要显示消息摘录。为此,我进行了字数统计,然后说了20个字(用空格检查)后,我截断了字符串并附加了View more定位标记。这会将其链接到网站的帖子页面,该页面包含完整的帖子。就像是:

嘿,这是一个示例帖子文本<b>message</b>Lorem ipsum dolor坐在椅子上,...<a href="someurl">查看更多</a>

问题:

在单词计数和截断期间,可能会截断html标记之间的字符串,因为我只是根据空间来计算单词。就像是:

我正在与您分享链接。<a style="color:...<a href="someurl">查看更多</a>

现在,这将破坏html。

可能的解决方案:

  • 在截断字符串之前,对它运行正则表达式以查找其中的所有html标记。
  • 使用indexOf()(或其他方法)查找每个标签的开始和结束索引。
  • 字数统计后,获取我需要截断的索引。
  • 现在看到索引是否与任何标签区域相交。
  • 如果确实相交,则只需将截断索引移到html标记的开头或结尾即可。

问题:

有一个更好的方法吗。我不知道我应该在Google上搜索哪些搜索字词,以获取有关此方面的帮助。

PS该代码是灵活的,如果有更好的解决方案,我可以更改流程。另外,我对职位的称呼也不好。如果可以,请将其修改为反映该问题的内容。


编辑:

这是我在亚历克斯回答后想到的。希望它可以帮助其他人:

/**
 * Counter: Takes a string and returns words and characters count
 * @param value
 * @returns obj: {
 *      'wordCount': (int),
 *      'totalChars': (int),
 *      'charCount': (int),
 *      'charCountNoSpace': (int)
 *  }
 */
var counter = function(value){
    var regex = /\s+/gi;
    if (!value.length) {
        return {
            wordCount: 0,
            totalChars: 0,
            charCount: 0,
            charCountNoSpace: 0
        };
    }
    else {
        return {
            wordCount: value.trim().replace(regex, ' ').split(' ').length,
            totalChars: value.length,
            charCount: value.trim().length,
            charCountNoSpace: value.replace(regex, '').length
        };
    }
}


/**
 * htmlSubString - Creates excerpt from markup(or even plain text) without creating malformed HTML tags
 * @param markup {string} - Markup/text to take excerpt out of
 * @param limit {int} - Total word count of excerpt. Note that only text (not the html tag) counts as a valid word.
 * @returns {string} - Excerpt
 */
var htmlSubString = function(markup, limit){
    var htmlParser = require("htmlparser2");
    var tagCount = 0;
    var wordCount = 0;
    var excerpt = '';

    function addToExcerpt(type, text, attribs) {
        if ((wordCount >= limit && tagCount == 0) || (tagCount === 1 && type === 'tagOpen' && wordCount >= limit)) {
            return false;
        }
        else if (wordCount < limit || tagCount) {
            if (type === 'text') {
                var wordCountSubString = $scope.counter(text).wordCount;
                if (wordCountSubString + wordCount > limit && tagCount === 0) {
                    var length = limit - wordCount;
                    var wordList = text.trim().split(' ');

                    for (var i = 0; i < length; i++) {
                        excerpt += ' ' + wordList[i];
                        wordCount++;
                    }
                } else {
                    wordCount += wordCountSubString;
                    excerpt += text;
                }

            } else if (type === 'tagOpen') {
                excerpt += '<' + text;
                for (var prop in attribs) {
                    excerpt += ' ' + prop + '="' + attribs[prop] + '"';
                }
                excerpt += '>';
            } else if (type === 'tagClose') {
                excerpt += '</' + text + '>';
            }
        }

        return true;
    }

    var parser = new htmlParser.Parser({
        onopentag: function (name, attribs) {
            if(wordCount < limit){
                ++tagCount;
                addToExcerpt('tagOpen', name, attribs);
            }
        },
        ontext: function (text) {
            if(wordCount < limit){
                addToExcerpt('text', text);
            }
        },
        onclosetag: function (tagName) {
            if(wordCount < limit || tagCount > 0){
                addToExcerpt('tagClose', tagName);
                --tagCount;
            }
        }
    });

    parser.write(markup);
    parser.end();

    return excerpt;
}

用法:

var wordCountLimit = 20;
var markup = "/* some markup/text */";
var excerpt = htmlSubString(markup, wordCountLimit);
雪佛兰

现在,您绝对可以找到一些与正则表达式匹配的HTML标记。就是说,我不建议这样做。起初,您会很高兴,并且一切都会正常进行。然后明天您会发现一个小的情况。“不用担心!” 您会说,当您修改表达式以解决差异时。然后第二天,进行一次新的调整,再进行一次新调整,等等,直到您无法忍受为止。

我强烈建议您找到一个已经建立的HTML解析库。npm上似乎有很多。这个似乎很受欢迎。

PS-您的问题做得很好。我希望更多的问题能花更多的时间并提供更多的细节:)

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在不创建格式错误的HTML标签的情况下拆分字符串?

来自分类Dev

如何在不格式化为字符串的情况下获取 24 中的时间

来自分类Dev

如何分解字符串,编辑数据,然后在原始分隔符仍然存在的情况下使其内爆?

来自分类Dev

如何在 Codeigniter 中分解字符串

来自分类Dev

如何在不创建新行的情况下将字符追加到字符串的末尾

来自分类Dev

如何在不创建新数组的情况下用字符串填充字节数组?

来自分类Dev

如何在不包含奇怪字符的情况下使用XOR加密字符串?

来自分类Dev

如何在不添加任何字符的情况下将列表合并为字符串?

来自分类Dev

如何在不创建临时字符串的情况下将字符串的一部分转换为int / float / vector3等?

来自分类Dev

如何在不破坏标签的情况下截断html?

来自分类Dev

如何在给定未知格式字符串的情况下对数组进行sprintf?

来自分类Dev

如何在不添加尾随'\ n'的情况下对字符串进行哈希处理?

来自分类Dev

如何在不获取空值到输出数组的情况下拆分字符串

来自分类Dev

如何在不丢失Java单词的情况下拆分字符串?

来自分类Dev

如何在不丢失单词的情况下分割字符串?

来自分类Dev

如何在不评估的情况下解除列表/元组的字符串

来自分类Dev

如何在不枚举查询的情况下将字符串转换为int

来自分类Dev

如何在不担心可变借贷的情况下分割字符串?

来自分类Dev

如何在不添加逗号的情况下将对象转换为字符串?

来自分类Dev

如何在不添加结尾的情况下用空格连接字符串?

来自分类Dev

如何在不丢失顺序的情况下删除 Swift 中字符串的重复行?

来自分类Dev

如何在不访问数据库连接的情况下 Mysqli 转义字符串?

来自分类Dev

如何在不编辑代码的情况下查看函数/类文档字符串

来自分类Dev

如何在不知道字符串格式的情况下将字符串转换为日期

来自分类Dev

如何在没有已知格式的情况下将字符串分成不同的子字符串

来自分类Dev

如何在不破坏字符串的情况下将字符串添加到set()中?

来自分类Dev

如何在不使用eval的情况下从字符串创建方法调用

来自分类Dev

如何在不进行实际打印的情况下从(错误)对象中生成字符串?

来自分类Dev

如何在不创建命名字符串流的情况下流式处理字符串?

Related 相关文章

  1. 1

    如何在不创建格式错误的HTML标签的情况下拆分字符串?

  2. 2

    如何在不格式化为字符串的情况下获取 24 中的时间

  3. 3

    如何分解字符串,编辑数据,然后在原始分隔符仍然存在的情况下使其内爆?

  4. 4

    如何在 Codeigniter 中分解字符串

  5. 5

    如何在不创建新行的情况下将字符追加到字符串的末尾

  6. 6

    如何在不创建新数组的情况下用字符串填充字节数组?

  7. 7

    如何在不包含奇怪字符的情况下使用XOR加密字符串?

  8. 8

    如何在不添加任何字符的情况下将列表合并为字符串?

  9. 9

    如何在不创建临时字符串的情况下将字符串的一部分转换为int / float / vector3等?

  10. 10

    如何在不破坏标签的情况下截断html?

  11. 11

    如何在给定未知格式字符串的情况下对数组进行sprintf?

  12. 12

    如何在不添加尾随'\ n'的情况下对字符串进行哈希处理?

  13. 13

    如何在不获取空值到输出数组的情况下拆分字符串

  14. 14

    如何在不丢失Java单词的情况下拆分字符串?

  15. 15

    如何在不丢失单词的情况下分割字符串?

  16. 16

    如何在不评估的情况下解除列表/元组的字符串

  17. 17

    如何在不枚举查询的情况下将字符串转换为int

  18. 18

    如何在不担心可变借贷的情况下分割字符串?

  19. 19

    如何在不添加逗号的情况下将对象转换为字符串?

  20. 20

    如何在不添加结尾的情况下用空格连接字符串?

  21. 21

    如何在不丢失顺序的情况下删除 Swift 中字符串的重复行?

  22. 22

    如何在不访问数据库连接的情况下 Mysqli 转义字符串?

  23. 23

    如何在不编辑代码的情况下查看函数/类文档字符串

  24. 24

    如何在不知道字符串格式的情况下将字符串转换为日期

  25. 25

    如何在没有已知格式的情况下将字符串分成不同的子字符串

  26. 26

    如何在不破坏字符串的情况下将字符串添加到set()中?

  27. 27

    如何在不使用eval的情况下从字符串创建方法调用

  28. 28

    如何在不进行实际打印的情况下从(错误)对象中生成字符串?

  29. 29

    如何在不创建命名字符串流的情况下流式处理字符串?

热门标签

归档