每个新单词瑞典字符和html标记的大写

时间:2017-08-09 07:33:23

标签: javascript regex

我被指出这篇文章似乎没有遵循我的标准: Replace a Regex capture group with uppercase in Javascript

我正在尝试制作一个正则表达式:

  • 通过为每个单词的第一个字母添加大写来格式化字符串,为其余字符添加小写
  • 忽略HTML标记
  • 接受瑞典字符(åäöÅÄÖ)

说我有这个字符串:

<b>app</b>le store östersund

然后我希望它(用大写字符标记的更改)

<b>App</b>le Store Östersund

我一直在玩它,而我最接近的是:

  

(?!?([^&LT;])*&GT;)[åäöÅÄÖ] | \ S \ B \瓦特

导致

<b>app</b>le Store Östersund

或者这个

  

/(?!([^&LT;])*&GT;)[åäöÅÄÖ] | \ S \ B \ W /克

导致

<B>App</B>Le store Östersund

这是一个小提琴: http://refiddle.com/refiddles/598aabef75622d4a531b0000

非常感谢任何帮助或建议。

2 个答案:

答案 0 :(得分:2)

单独使用regexp是不可能的,因为regexp并不了解HTML结构。 [*]相反,我们需要处理每个文本节点,并在单词继续跨越不同文本节点的情况下,通过我们的逻辑来确定单词的开头是什么。如果字符前面有一个空格,或者如果它位于字符串的开头,并且它是第一个文本节点,或者前一个文本节点以空格结束,则该字符位于该单词的开头。

&#13;
&#13;
function htmlToTitlecase(html, letters) {
  let div = document.createElement('div');
  let re = new RegExp("(^|\\s)([" + letters + "])", "gi");
  div.innerHTML = html;
  let treeWalker = document.createTreeWalker(div, NodeFilter.SHOW_TEXT);
  let startOfWord = true;
  while (treeWalker.nextNode()) {
    let node = treeWalker.currentNode;
    node.data = node.data.replace(re, function(match, space, letter) {
      if (space || startOfWord) {
        return space + letter.toUpperCase();
      } else {
        return match;
      }
    });
    startOfWord = node.data.match(/\s$/);
  }
  return div.innerHTML;
}

console.log(htmlToTitlecase("<b>app</b>le store östersund", "a-zåäö"));
// <b>App</b>le Store Östersund
&#13;
&#13;
&#13;

[*]也许可能,但即使如此,它也会非常丑陋,因为它需要覆盖大量的角落案件。也可能需要比JavaScript更强大的RegExp引擎,如Ruby或Perl。

修改

  

即使只指定非常简单的html标签?目前我唯一需要覆盖的是<b></b>

这个问题没有说明。该解决方案足以适用于任何标记(包括简单标记)。但...

&#13;
&#13;
function simpleHtmlToTitlecaseSwedish(html) {
  return html.replace(/(^|\s)(<\/?b>|)([a-zåäö])/gi, function(match, space, tag, letter) {
    return space + tag + letter.toUpperCase();
  });
}
console.log(simpleHtmlToTitlecaseSwedish("<b>app</b>le store östersund", "a-zåäö"));
&#13;
&#13;
&#13;

答案 1 :(得分:1)

我有一个几乎只使用正则表达式的解决方案。这可能不是最直观的方式,但它应该是有效的,我发现它很有趣:)

你必须在你的字符串的末尾附加每个小写字符后跟它们的大写字母,就像这样(它也必须在我的正则表达式前面加上空格):
aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZåÅäÄöÖ
(我不知道丢失了哪些字母,我对瑞典字母一无所知,对不起......我指望你纠正它!)

然后你可以使用以下正则表达式:
(?![^<]*>)(\s<[^/]*?>|\s|^)([\wåäö])(?=.*\2(.)\S*$)|[\wåÅäÄöÖ]+$
替换为:
$1$3

测试here

这是一个有用的JavaScript代码:

&#13;
&#13;
// Initialization
var regex = /(?![^<]*>)(\s<[^/]*?>|\s|^)([\wåäö])(?=.*\2(.)\S*$)|[\wåÅäÄöÖ]+$/g;
var string = "test <b when=\"2>1\">ap<i>p</i></b>le store östersund";

// Processing
result = string + " aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZåÅäÄöÖ";
result = result.replace(regex, "$1$3");

// Display result
console.log(result);
&#13;
&#13;
&#13;

编辑:我忘了处理字符串中的第一个字,它已经更正了:)