【问题标题】:Neglect a pattern using Regex使用正则表达式忽略模式
【发布时间】:2019-12-28 03:28:12
【问题描述】:

在使用正则表达式搜索子字符串时,我需要帮助以忽略模式。 例如,在下面的字符串中

Hello *testing [*_*] message* text

Hello *testing [_*_*] message* text * additional* message

Hello testing [*_*_] message* text * additional* message*

Hello testing [_*_*_] message* text * additional* message*

我需要找出所有 * 以替换为 html 粗体标记,方括号“[]”内的那些除外。 但是当我运行这个正则表达式[*]((?s).*?)[*] 时,它还在[] 中包含*,并替换它们。搜索时如何忽略 [**] 组合。

任何帮助将不胜感激。

编辑:

基本上,如果给定字符(例如*)在方括号[] 内,我想忽略匹配。

【问题讨论】:

  • 你能使用否定的环视吗?如果是这样,类似'(?<!\[)\*(?!])' 的内容将匹配*,除非它前面或后面有[]
  • 状态机可能会给出更好的结果
  • @Cristik 在实践中它可能更容易实现和调试。但是请注意,有限状态机等价于正则表达式。
  • @Sulthan 我认为情况正好相反:正则表达式解析器使用状态机。另外,不确定为这种情况编写正确的正则表达式有多容易,这就是我推荐自定义解析器的原因\
  • 这真的是为了 swift 还是一般的正则表达式问题?

标签: swift regex swift5


【解决方案1】:

模式(?<!\[)\*(?!\])(.*?)(?<!\[)\*(?!\]) - 虽然有点丑 - 在 cmets 中实现了您真正想要的。

对于字符串Hello *testing [*_*] message* text * additional* message 它返回testing [*_*] message, additional

(?<!\[)\*(?!\]) 部分只匹配 有效 "*"

Here 是这样工作的。

【讨论】:

  • 目前我不在系统中,尝试后会回复。
  • 嗨@xcan,它适用于场景,我已经在给定的字符串中进行了描述,并按预期返回返回结果。但在一种情况下失败了,当在 [**] 之间放置一个或多个字符时。
  • 基本上我想忽略前* 的给定字符,如果它在[] 之间,无论它在方括号中的位置如何。我在这里放了一些案例regex101.com/r/uN0tQb/2
  • 你好@Surjeet,我对这个正则表达式使用了负前瞻和后视。任何类型的前瞻都需要固定大小的字符。我不认为你想要的可以用一个正则表达式或至少我能写的任何一个正则表达式来完成。我建议您在使用正则表达式之前进行一些预处理或为此编写自定义解析器。
  • 例如提取“[]”为它们放置一个特殊的索引,使用我给的正则表达式然后重新插入它们。 Hello *testing [*_*] message* text *some [_*_*] additional* text -> Hello *testing $%1 message* text *some $%2 additional* text -> 我给的正则表达式->Hello <b>testing $%1 message<\b> text <b>some $%2 additional<\b> text ->重新插入 -> Hello <b>testing [*_*] message<\b> text <b>some [_*_*] additional<\b>
【解决方案2】:

模式(\s+\*)|(\*\s+) 怎么样,它匹配* 加上它之后或之前的任意数量的空格。

编辑

(\*\s*\w*\s*\*)|(\*\s*\w*\s*\[\*.*\*\]\s*\w*\s*\*)

您可以查看here

【讨论】:

  • 感谢您的回复,但我的要求是在 [] 中的 * 忽略 * 对中获取值。因此,对于我的问题中的上述消息,应该赋予第一个和最后一个 * 的价值。
  • @Surjeet 它确实忽略了[*_*],为您提供了 2 个匹配组,其中包含字符串中的第一个和最后一个 *
  • 是的,确实如此。但我需要一个包含 * 内的子字符串作为值的组。如果在 * 之前/之后没有空间,这也将不起作用
  • 如果你在我的问题中运行正则表达式,它会给我我想要的价值,但我无法忽略 [*_*]
  • @Surjeet 好的,我让你试着弄清楚是否可以
【解决方案3】:

您可以匹配您不想要的并使用alternation 将星号保留在捕获组中。

在替换中,将第一个捕获组的值包装在 html 粗体标记中

\[[^*\]]*\*[^\]]*\]|(\*)

这将匹配:

  • \[[^*\]]*\*[^\]]*\] 匹配 [ ... ]* 之间使用 negated character class [^
  • |或者
  • (\*)捕获组1,匹配一个星号

Regex demo

或者使用较短的版本,它不会考虑匹配星号,而是从开头匹配到右方括号

\[[^\]]+\]|(\*)

Regex demo

【讨论】:

  • 在方括号内时不会忽略 *。
  • @Surjeet 我没有使用 swift 的经验,但是如果您在捕获组 1 中有值,您可以使用代码进行检查。如果是这种情况,则返回包含在 html 粗体标签中的组 1。如果没有值,则仅返回匹配项。也许this page 会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-31
  • 1970-01-01
  • 2017-04-23
  • 2021-09-13
相关资源
最近更新 更多