正则表达式:类似松弛的"降价",用于匹配一个格式字符



我尝试过研究这个,但只能弄清楚如何让我的搜索词如此精确。

我希望用户能够用符号包围文本,_*~等,以进行类似降价的格式,基本上是Slack的方式。我让它工作得很好,但我有一个问题。

当用户键入_bold_时,我渲染<strong>bold</strong>,这是所需的效果。但是当用户键入__bold__时,我宁愿只__bold__时会<strong>_bold_</strong>

这是我的正则表达式:

const rules = [
{regex: /_{1}(.+?)_{1}/g, replacement: '<em>$1</em>'},
{regex: /*{1}(.+?)*{1}/g, replacement: '<strong>$1</strong>'},
// etc
];

然后我正在运行:

let formattedText = '__some text__'; // the user input
rules.forEach(rule => formattedText = formattedText.replace(rule.regex, rule.replacement));

它只匹配带有{1}的那个。但是我如何让它忽略有多个情况的情况呢?

您可以使用

{regex: /(^|[^_])_(?!_)((?:[^]*?[^_])?)_(?!_)/g, replacement: '$1<em>$2</em>'}

请参阅正则表达式演示。

  • (^|[^_])- 组 1(引用替换模式中的$1,因为此文本应放回结果中(:字符串开头或除_以外的任何字符
  • _(?!_)-_后不跟_
  • ((?:[^]*?[^_])?)- 组 2(引用替换模式中的$2(:任何 0+ 字符 ([^]*?( 尽可能少 (*?(,后跟除_、零或一次以外的字符(可选(
  • _(?!_)-_后没有_

首先,Slack 不支持降价格式(也在此处注明(,但具有类似的更简单的标记语言:

Slack 消息可以使用简单的标记语言进行格式化,类似于 降价。支持的格式包括:precode体,粗体,甚至~删除~.;

无论如何,你最好的选择是使用一个流行的降价库,比如 Showdown,或者如果你真的想保持简单,你可以使用这样的东西:

;(function() { "use strict";
var
	output = "",
	BLOCK = "block",
	INLINE = "inline",
	/**
	 * Used to attach MarkdownToHtml object to `window` in browser
	 * context, or as an AMD module where appropriate.
	 * @type {Object}
	 */
	exports,
	/**
	 * An array of parse rule descriptor objects. Each object has two keys;
	 * pattern (the RegExp to match), and replace (the replacement string or
	 * function to execute).
	 * @type {Array}
	 */
	parseMap = [
		{
			// <h1>
			// A line starting with 1-6 hashes.
			pattern: /(#{1,6})([^n]+)/g,
			replace: "<h$L1>$2</h$L1>",
			type: BLOCK,
		},
		{
			// <p>
			// Any line surrounded by newlines that doesn't start with
			// an HTML tag, asterisk or numeric value with dot following.
			pattern: /n(?!</?w+>|s?*|s?[0-9]+|>|&gt;|-{5,})([^n]+)/g,
			replace: "<p>$1</p>",
			type: BLOCK,
		},
		{
			// <blockquote>
			// A greater-than character preceding any characters.
			pattern: /n(?:&gt;|>)W*(.*)/g,
			replace: "<blockquote><p>$1</p></blockquote>",
			type: BLOCK,
		},
		{
			// <ul>
			//
			pattern: /ns?*s*(.*)/g,
			replace: "<ul>nt<li>$1</li>n</ul>",
			type: BLOCK,
		},
		{
			// <ol>
			//
			pattern: /ns?[0-9]+.s*(.*)/g,
			replace: "<ol>nt<li>$1</li>n</ol>",
			type: BLOCK,
		},
		{
			// <strong>
			// Either two asterisks or two underscores, followed by any
			// characters, followed by the same two starting characters.
			pattern: /(**|__)(.*?)1/g,
			replace: "<strong>$2</strong>",
			type: INLINE,
		},
		{
			// <em>
			// Either one asterisk or one underscore, followed by any
			// characters, followed by the starting character.
			pattern: /(*|_)(.*?)1/g,
			replace: "<em>$2</em>",
			type: INLINE,
		},
		{
			// <a>
			// Not starting with an exclamation mark, square brackets
			// surrounding any characters, followed by parenthesis surrounding
			// any characters.
			pattern: /([^!])[([^[]+)](([^)]+))/g,
			replace: "$1<a href="$3">$2</a>",
			type: INLINE,
		},
		{
			// <img>
			// Starting with an exclamation mark, then followed by square
			// brackets surrounding any characters, followed by parenthesis
			// surrounding any characters.
			pattern: /![([^[]+)](([^)]+))/g,
			replace: "<img src="$2" alt="$1" />",
			type: INLINE,
		},
		{
			// <del>
			// Double tilde characters surrounding any characters.
			pattern: /~~(.*?)~~/g,
			replace: "<del>$1</del>",
			type: INLINE,
		},
		{
			// <code>
			//
			pattern: /`(.*?)`/g,
			replace: "<code>$1</code>",
			type: INLINE,
		},
		{
			// <hr>
			//
			pattern: /n-{5,}n/g,
			replace: "<hr />",
			type: BLOCK,
		},
	],
$$;
/**
* Self-executing function to handle exporting the parse function for
* external use.
*/
(function go() {
	// Export AMD module if possible.
	if(typeof module !== "undefined"
	&& typeof module.exports !== "undefined") {
		exports = module.exports;
	}
	// Otherwise check for browser context.
	else if(typeof window !== "undefined") {
		window.MarkdownToHtml = {};
		exports = window.MarkdownToHtml;
	}
	exports.parse = parse;
})();
/**
* Parses a provided Markdown string into valid HTML.
*
* @param  {string} string Markdown input for transformation
* @return {string}        Transformed HTML output
*/
function parse(string) {
	// Pad with newlines for compatibility.
	output = "n" + string + "n";
	parseMap.forEach(function(p) {
		// Replace all matches of provided RegExp pattern with either the
		// replacement string or callback function.
		output = output.replace(p.pattern, function() {
			// console.log(this, arguments);
			return replace.call(this, arguments, p.replace, p.type);
		});
	});
	// Perform any post-processing required.
	output = clean(output);
	// Trim for any spaces or newlines.
	output = output.trim();
	// Tidy up newlines to condense where more than 1 occurs back to back.
	output = output.replace(/[n]{1,}/g, "n");
	return output;
}
function replace(matchList, replacement, type) {
	var
		i,
	$$;
	for(i in matchList) {
		if(!matchList.hasOwnProperty(i)) {
			continue;
		}
		// Replace $n with the matching regexp group.
		replacement = replacement.split("$" + i).join(matchList[i]);
		// Replace $Ln with the matching regexp group's string length.
		replacement = replacement.split("$L" + i).join(matchList[i].length);
	}
	if(type === BLOCK) {
		replacement = replacement.trim() + "n";
	}
	return replacement;
}
function clean(string) {
	var cleaningRuleArray = [
		{
			match: /</([uo]l)>s*<1>/g,
			replacement: "",
		},
		{
			match: /(</w+>)</(blockquote)>s*<2>/g,
			replacement: "$1",
		},
	];
	cleaningRuleArray.forEach(function(rule) {
		string = string.replace(rule.match, rule.replacement);
	});
	return string;
}
})();
var element = document.getElementById("example-markdown-content");
console.log(MarkdownToHtml.parse(element.innerHTML));
<div id="example-markdown-content">
# Hello, Markdown!
Here is some example **formatting** in _Markdown_.
</div>

即使这太多了,您也可以轻松修剪它,因为它非常简单。我想这将为您节省大量时间。

最新更新