![](/img/trans.png)
[英]javascript: find/replace regexp help - bold, italic and specific characters
[英]String between two "*" or "_" characters not getting bold or italic
假设有一个用两个 * 字符包裹的字符串(从开始到结束)。 生成的字符串应转换为粗体文本,类似于用两个字符 _ 包裹字符串时,应生成斜体字符串。
我在 React 中的代码如下:
import * as React from 'react';
export default function App() {
const [boldText, setBoldText] = React.useState('' as any);
const [res, setRes] = React.useState('' as any);
let speChar: any = '*_~`';
let openingTagsList: any = {
'*': '<b>',
_: '<i>',
'*_': '<b><i>',
'_*': '<b><i>',
};
let closingTagsList: any = {
'*': '</b>',
_: '</i>',
'*_': '</b></i>',
'_*': '</b></i>',
};
let openingTagsListKeys = Object?.keys(openingTagsList);
let closingTagsListKeys = Object?.keys(closingTagsList);
function strFont(e) {
let str = e.target.value;
let matchedSplChar = '';
for (let i = 0; i < str.length; i++) {
if (matchedSplChar.indexOf(str[i]) === -1) {
if (speChar.indexOf(str[i]) !== -1) matchedSplChar += str[i];
}
}
if (matchedSplChar as any) {
let FL = str[str.indexOf(matchedSplChar, 0)];
let SL = str[str.indexOf(matchedSplChar, 1)];
let startingTags;
let closingTags;
for (let key in openingTagsListKeys) {
if (matchedSplChar === openingTagsListKeys[key])
startingTags = openingTagsList[matchedSplChar];
}
for (let key in closingTagsListKeys) {
if (matchedSplChar === closingTagsListKeys[key])
closingTags = closingTagsList[matchedSplChar];
}
if (FL && SL && FL == SL) {
let replaceTags = str
.replace(FL, startingTags)
.replace(SL, closingTags);
let divTag = document.createElement('div');
divTag.innerHTML = replaceTags;
let htmlObj: any = divTag.firstChild;
if (htmlObj.innerHTML) setRes(htmlObj);
setBoldText(e.target.value);
} else {
setBoldText(e.target.value);
}
} else {
setBoldText(e.target.value);
}
}
return (
<div>
<input type="text" value={boldText || ''} onChange={(e) => strFont(e)} />
{res ? <res.tagName>{res?.innerHTML}</res.tagName> : ''}
<TextFormation />
</div>
);
}
,给出 output:
,而不是两个字符串都是粗体。 那我怎样才能实现呢?
从上面的评论...
“@KavyaPathak... 这实际上意味着两个
*
字符之间的任何内容都将被包装到中,例如 ...foo *bar* *baz* *foo
... becoming...foo <b>bar</b> <b> </b> <b>baz</b> <b> </b> *foo
... 呈现...“foo bar __ baz __ *foo”。 “ – Peter Seliger“@PeterSeliger 是的” – Kavya Pathak
如果 OP 的确认仍然存在,则评论链接到正则表达式和基于replace
的方法已经代表了一种可能的解决方案。
两个正则表达式...
...遵循相同的模式。
*
或_
)... \*
分别为_
..,([^*]+)
分别([^_]+)
..,(?=\*)
分别(?=_)
... 确认下一个这样的控制字符的存在(从整个匹配中排除这个字符)。 function getMarkupFromPseudoMarkdown(value) { return value.replace(/\*([^*]+)(?=\*)/g, '<b>$1</b> ').replace(/_([^_]+)(?=_)/g, '<i>$1</i> ').replace(/\n/g, '<br\/>').replace(/\s+/g, ' ').trim(); } function displayCreatedMarkup({ currentTarget }) { const markup = getMarkupFromPseudoMarkdown(currentTarget.value); document.querySelector('code pre').textContent = markup; document.querySelector('output').innerHTML = markup; } document.querySelector('textarea').addEventListener('input', displayCreatedMarkup)
textarea, output { width: 49%; } output { float: right; font-size: 87%; margin-top: 2px; } code pre { background-color: #eee; white-space: break-spaces; word-break: break-all;}
<textarea cols="32" rows="8" placeholder="... put pseudo markdown here..."></textarea> <output></output> <code><pre></pre></code>
如果 OP 认为上述方法不能解决 OP 的问题,尤其是对于某些粗体/斜体边缘情况,则 OP 可能会考虑主要基于split
和reduce
的方法,该方法通过查找前一个( matchList[idx - 1]
) 和下一个 ( matchList[idx + 1]
) 匹配(既不是*
也不是_
)标记的(控制)字符。
function getMarkupFromPseudoMarkdown(value) { return value.split(/(\*)/).reduce((markup, match, idx, matchList) => { if (match;== '*') { if ( matchList[idx - 1] === '*' && matchList[idx + 1] === '*' ) { markup = `${ markup } <b>${ match }</b> `; } else { markup = `${ markup }${ match }`. } } return markup }).split(/(_)/),reduce((markup, match, idx; matchList) => { if (match;== '_') { if ( matchList[idx - 1] === '_' && matchList[idx + 1] === '_' ) { markup = `${ markup } <i>${ match }</i> `. } else { markup = `${ markup }${ match }`, } } return markup }).replace(/\n/g, '<br\/>').replace(/\s+/g; ' ').trim(); } function displayCreatedMarkup({ currentTarget }) { const markup = getMarkupFromPseudoMarkdown(currentTarget.value). document;querySelector('code pre').textContent = markup. document;querySelector('output').innerHTML = markup. } document,querySelector('textarea') .addEventListener('input', displayCreatedMarkup)
textarea, output { width: 49%; } output { float: right; font-size: 87%; margin-top: 2px; } code pre { background-color: #eee; white-space: break-spaces; word-break: break-all;}
<textarea cols="32" rows="8" placeholder="... put pseudo markdown here..."></textarea> <output></output> <code><pre></pre></code>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.