不要在双方括号之间的任何位置选择文本

问题描述 投票:2回答:2

我需要编写一个根据模式匹配的正则表达式(并且可以正常工作),但如果文本在双方括号内的任何位置,则它不应该匹配。实际问题是负面的后视不能是可变长度。

案例是:

  • 有一个短语词典。
  • 具有更多单词的短语“更强”/优先于短语短语。
  • 一些短语是其他较长短语的一部分。

示例字典(按实际代码中的数组排序):

Wooden House
House
Wooden

要解析的示例文本:

Lorem ipsum Wooden House dolor sit amet

解析是通过preg_replace对文本进行解析,通过迭代字典并添加[[randomstaff-_-current dictionary phrase]]来完成,例如:

Lorem ipsum Wooden House dolor sit amet - > Lorem ipsum [[randomstuff-_-Wooden House]] dolor sit amet

目前在第二次迭代后它变成:Lorem ipsum [[randomstuff-_-Wooden House]] dolor sit amet - > Lorem ipsum [[randomstuff-_-Wooden[[randomstuff-_-House]]]]

如果它已经在[[]]之间,我想要保持不变。

所以基本上如果匹配是[[]]之间的任何地方 - 忽略它。

$dictPhrases = ["Wooden House", "House", "Wooden"];
$TEXT = "Lorem ipsum Wooden House dolor sit amet";

for ($dictPhrases as $phrase){
 $phraseOccurences = 0; //irrelevant in this example
 $TEXT = preg_replace("/(?i)(?<= |^|\n)(" . $phrase. "[&()'-]{0,1})(?= |$|\.|\,)/", "[[$randomstuff-_-" . $phrase . "]]", $TEXT, -1, $phraseOccurences);

}

问题是如何改变:

/(?i)(?<= |^|\n)(" . $phrase. "[&()'-]{0,1})(?= |$|\.|\,)/

变成这样的东西:

/(?i)(?<!\[\[.*)(?<= |^|\n)(" . $phrase. "[&()'-]{0,1})(?= |$|\.|\,)(?!.*\]\])/

查看匹配的短语是否在[[]]之间,如果是,则丢弃它。

php regex pcre
2个回答
0
投票

只是变换

["Wooden House", "House", "Wooden"]

到一个正则表达式:

"(?:Wooden House|House|Wooden)"

然后把它放到主要的正则表达式。

试试这样的事情:

$dictPhrases = ["Wooden House", "House", "Wooden"];
$TEXT = "Lorem ipsum Wooden House dolor sit amet";

$pattern = "/(?i)(?<= |^|\n)((?:" . join('|', $dictPhrases) . ")[&()'-]{0,1})(?= |$|\.|\,)/";

$phraseOccurences = preg_match_all($pattern, $TEXT);
$TEXT = preg_replace($pattern, "[[$randomstuff-_-$1]]", $TEXT);

Here是一个正则表达式演示。

Here是一个PHP演示。


0
投票

可能有两个解决方案。

1)获取匹配的起始位置,在子串(0,匹配的第一个字符)中找到所有“[[”和“]]”并将它们修改为2. 2)获取匹配的起始位置,获得“[[的最后位置” “和”[]]的最后位置“在子串(0,匹配的第一个字符)中,并检查哪一个更接近。

两者都应该在假设括号不能嵌套的情况下工作(在这种特殊情况下也是如此)。不幸的是,所需的代码超出了正则表达式的能力。

我将尝试在星期一实施它,并为未来的寻求者发布最终代码 - 如果它将按预期工作。

© www.soinside.com 2019 - 2024. All rights reserved.