正则表达式:匹配下划线包裹的单词,除非它们以 @ / # 开头
Regex: match underscore-wrapped words unless they start with @ / #
我正在尝试通过传入自定义正则表达式来解决 Tiptap(Vue 的所见即所得编辑器)中的 this bug,以便在 Markdown (_value_
) 中识别斜体符号的正则表达式将不适用于以 @
或 #
开头的字符串,例如#some_tag_value
不会转换为 #sometagvalue.
到目前为止,这是我的正则表达式 - /(^|[^@#_\w])(?:\w?)(_([^_]+)_)/g
编辑:在@Wiktor Stribiżew /(^|[^@#_\w])(_([^_]+)_)/g
的帮助下新的正则表达式
虽然它满足了大多数常见情况,但目前仍然失败
下划线是中间词,例如ant_farm_应该匹配(antfarm)
我在这里也提供了一些"should match"和"should not match"案例https://regexr.com/50ibf以便于测试
应该匹配(下划线之间)
_italic text here_
police_woman_
_fire_fighter
a thousand _words_
_brunch_ on a Sunday
不应该匹配
@ta_g_
__value__
#some_tag_value
@some_value_here
@some_tag_
#some_val_
#_hello_
对于科学来说,这个怪物在 Chrome(和 Node.js)中起作用。
let text = `
<strong>Should match</strong> (between underscores)
_italic text here_
police_woman_
_fire_fighter
a thousand _words_
_brunch_ on a Sunday
<strong>Should not match</strong>
@ta_g_
__value__
#some_tag_value
@some_value_here
@some_tag_
#some_val_
#_hello_
`;
let re = /(?<=(?:\s|^)(?![@#])[^_\n]*)_([^_]+)_/g;
document.querySelector('div').innerHTML = text.replace(re, '<em></em>');
div { white-space: pre; }
<div/>
这会将 _something_
捕获为完全匹配,并将 something
作为第一个捕获组(以便删除下划线)。你不能只捕获 something
,因为那样你就无法分辨下划线内部和外部的内容(用 (?<=(?:\s|^)(?![@#])[^_\n]*_)([^_]+)(?=_)
试试)。
有两点阻碍了它的普遍适用:
- 并非所有 JavaScript 引擎都支持后视
- 大多数正则表达式引擎不支持可变长度回顾
编辑:这有点强大,并且应该允许您另外 match_this_and_that_ but not @match_this_and_that
正确:
/(?<=(?:\s|^)(?![@#])(?!__)\S*)_([^_]+)_/
解释:
_([^_]+)_ Match non-underscory bit between two underscores
(?<=...) that is preceded by
(?:\s|^) either a whitespace or a start of a line/string
(i.e. a proper word boundary, since we can't use `\b`)
\S* and then some non-space characters
(?![@#]) that don't start with `@`, `#`,
(?!__) or `__`.
您可以使用以下模式:
(?:^|\s)[^@#\s_]*(_([^_]+)_)
详情
(?:^|\s)
- 字符串或空格的开头
[^@#\s_]*
- 除了 @
、#
、_
和空格 之外的 0 个或更多字符
(_([^_]+)_)
- 第 1 组:_
,除 _
之外的 1+ 个字符(捕获到第 2 组),然后是 _
.
这里有一些东西,它不像其他答案那么紧凑,但我认为它更容易理解发生了什么。匹配组 </code> 就是你想要的。 </p>
<p><em>需要多行标志</em></p>
<pre><code>^([a-zA-Z\s]+|_)(([a-zA-Z\s]+)_)+?[a-zA-Z\s]*?$
^
- 匹配行首
([a-zA-Z\s]+|_)
- 多个单词或 _
(([a-zA-Z\s]+)_)+?
- 多个单词后跟 _
至少一次,但最少匹配。
[a-zA-Z\s]*?
- 最后的话
$
- 行尾
综上所述细目匹配的事物之一
_<words>_
<words>_<words>_
<words>_<words>_<words>
_<words>_<words>
我正在尝试通过传入自定义正则表达式来解决 Tiptap(Vue 的所见即所得编辑器)中的 this bug,以便在 Markdown (_value_
) 中识别斜体符号的正则表达式将不适用于以 @
或 #
开头的字符串,例如#some_tag_value
不会转换为 #sometagvalue.
到目前为止,这是我的正则表达式 - /(^|[^@#_\w])(?:\w?)(_([^_]+)_)/g
编辑:在@Wiktor Stribiżew /(^|[^@#_\w])(_([^_]+)_)/g
虽然它满足了大多数常见情况,但目前仍然失败 下划线是中间词,例如ant_farm_应该匹配(antfarm)
我在这里也提供了一些"should match"和"should not match"案例https://regexr.com/50ibf以便于测试
应该匹配(下划线之间)
_italic text here_
police_woman_
_fire_fighter
a thousand _words_
_brunch_ on a Sunday
不应该匹配
@ta_g_
__value__
#some_tag_value
@some_value_here
@some_tag_
#some_val_
#_hello_
对于科学来说,这个怪物在 Chrome(和 Node.js)中起作用。
let text = `
<strong>Should match</strong> (between underscores)
_italic text here_
police_woman_
_fire_fighter
a thousand _words_
_brunch_ on a Sunday
<strong>Should not match</strong>
@ta_g_
__value__
#some_tag_value
@some_value_here
@some_tag_
#some_val_
#_hello_
`;
let re = /(?<=(?:\s|^)(?![@#])[^_\n]*)_([^_]+)_/g;
document.querySelector('div').innerHTML = text.replace(re, '<em></em>');
div { white-space: pre; }
<div/>
这会将 _something_
捕获为完全匹配,并将 something
作为第一个捕获组(以便删除下划线)。你不能只捕获 something
,因为那样你就无法分辨下划线内部和外部的内容(用 (?<=(?:\s|^)(?![@#])[^_\n]*_)([^_]+)(?=_)
试试)。
有两点阻碍了它的普遍适用:
- 并非所有 JavaScript 引擎都支持后视
- 大多数正则表达式引擎不支持可变长度回顾
编辑:这有点强大,并且应该允许您另外 match_this_and_that_ but not @match_this_and_that
正确:
/(?<=(?:\s|^)(?![@#])(?!__)\S*)_([^_]+)_/
解释:
_([^_]+)_ Match non-underscory bit between two underscores
(?<=...) that is preceded by
(?:\s|^) either a whitespace or a start of a line/string
(i.e. a proper word boundary, since we can't use `\b`)
\S* and then some non-space characters
(?![@#]) that don't start with `@`, `#`,
(?!__) or `__`.
您可以使用以下模式:
(?:^|\s)[^@#\s_]*(_([^_]+)_)
详情
(?:^|\s)
- 字符串或空格的开头[^@#\s_]*
- 除了@
、#
、_
和空格 之外的 0 个或更多字符
(_([^_]+)_)
- 第 1 组:_
,除_
之外的 1+ 个字符(捕获到第 2 组),然后是_
.
这里有一些东西,它不像其他答案那么紧凑,但我认为它更容易理解发生了什么。匹配组 </code> 就是你想要的。 </p>
<p><em>需要多行标志</em></p>
<pre><code>^([a-zA-Z\s]+|_)(([a-zA-Z\s]+)_)+?[a-zA-Z\s]*?$
^
- 匹配行首([a-zA-Z\s]+|_)
- 多个单词或_
(([a-zA-Z\s]+)_)+?
- 多个单词后跟_
至少一次,但最少匹配。[a-zA-Z\s]*?
- 最后的话$
- 行尾
综上所述细目匹配的事物之一
_<words>_
<words>_<words>_
<words>_<words>_<words>
_<words>_<words>