如何在不创建格式错误的 HTML 标签的情况下拆分字符串?
How do I break up a string without creating malformed HTML tags?
我在做什么:
- 在 NodeJS 中,我使用 MustacheJS 创建电子邮件模板,使用 JSON objects.
数组中的数据
- 模板中的 text/message 可以包含文本以及基本 html 标签(例如
b
p
和 a
)。
- 由于 space 的限制,我只需要显示消息的摘录。为此,我做了一个字数统计,然后让我们说 20 个字(由 spaces 检查)我 t运行 对字符串进行分类并附加
View more
锚标记。这会将它链接到网站的 post 页面,该页面包含完整的 post。类似于:
Hey this is a sample post text <b>message</b>
. Lorem ipsum dolor sit
amit... <a href="someurl">
View more</a>
问题:
在字数统计和 t运行cation 期间,我可能 t运行 将字符串放在 html 标记之间,因为我只是根据 space。类似于:
I am sharing a link with you. <a style="color:
... <a href="someurl">
View more</a>
现在这将打破 html。
可能的解决方案:
- 在 运行 匹配字符串之前,运行 一个正则表达式用于查找其中的所有 html 标签。
- 使用
indexOf()
(或其他方法)查找每个标签的开始和结束索引。
- 字数统计后,获取我需要运行分类的索引。
- 现在看看索引是否与任何标记区域相交。
- 如果相交,只需将 t运行cate 索引移动到 html 标记的开头或结尾。
问题:
有没有更好的方法来做到这一点。我不知道应该在 google 上搜索什么搜索词才能获得这方面的帮助。
P.S。代码很灵活,如果有明显更好的解决方案,我可以更改流程。另外,我不擅长 post 标题。如果可以,请修改为反映问题的内容。
编辑:
这是我在 Alex 的回答后想到的。希望对其他人有帮助:
/**
* 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 匹配正则表达式的标签。也就是说,我不推荐它。一开始你会很高兴,一切都会很好。然后明天你会发现一个小的边缘案例。 "No worries!" 当您修改表达式以解决差异时,您会说。然后第二天,一个新的调整,一个新的,又一个,等等,直到你不能再接受它。
我强烈建议您找到一个已经建立的 HTML 解析库。 npm 上似乎有很多。 This one 似乎相当受欢迎。
PS - 你的问题回答得很好。我希望更多的问题花费尽可能多的时间并提供尽可能多的细节:)
我在做什么:
- 在 NodeJS 中,我使用 MustacheJS 创建电子邮件模板,使用 JSON objects. 数组中的数据
- 模板中的 text/message 可以包含文本以及基本 html 标签(例如
b
p
和a
)。 - 由于 space 的限制,我只需要显示消息的摘录。为此,我做了一个字数统计,然后让我们说 20 个字(由 spaces 检查)我 t运行 对字符串进行分类并附加
View more
锚标记。这会将它链接到网站的 post 页面,该页面包含完整的 post。类似于:
Hey this is a sample post text
<b>message</b>
. Lorem ipsum dolor sit amit...<a href="someurl">
View more</a>
问题:
在字数统计和 t运行cation 期间,我可能 t运行 将字符串放在 html 标记之间,因为我只是根据 space。类似于:
I am sharing a link with you.
<a style="color:
...<a href="someurl">
View more</a>
现在这将打破 html。
可能的解决方案:
- 在 运行 匹配字符串之前,运行 一个正则表达式用于查找其中的所有 html 标签。
- 使用
indexOf()
(或其他方法)查找每个标签的开始和结束索引。 - 字数统计后,获取我需要运行分类的索引。
- 现在看看索引是否与任何标记区域相交。
- 如果相交,只需将 t运行cate 索引移动到 html 标记的开头或结尾。
问题:
有没有更好的方法来做到这一点。我不知道应该在 google 上搜索什么搜索词才能获得这方面的帮助。
P.S。代码很灵活,如果有明显更好的解决方案,我可以更改流程。另外,我不擅长 post 标题。如果可以,请修改为反映问题的内容。
编辑:
这是我在 Alex 的回答后想到的。希望对其他人有帮助:
/**
* 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 匹配正则表达式的标签。也就是说,我不推荐它。一开始你会很高兴,一切都会很好。然后明天你会发现一个小的边缘案例。 "No worries!" 当您修改表达式以解决差异时,您会说。然后第二天,一个新的调整,一个新的,又一个,等等,直到你不能再接受它。
我强烈建议您找到一个已经建立的 HTML 解析库。 npm 上似乎有很多。 This one 似乎相当受欢迎。
PS - 你的问题回答得很好。我希望更多的问题花费尽可能多的时间并提供尽可能多的细节:)