我正在使用可以使用MySQL和PHP搜索的长段文本。我希望能够找到并突出显示相关的搜索词,并使用正则表达式来隔离它们。
例如,我想转换一个Lorem ipsum段落,
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor
incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor
in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur
sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
laborum.
在搜索“dolor”时,进入类似的东西,
Lorem ipsum *dolor* sit amet ... labore et *dolor*e magna aliqua ... aute irure *dolor* in reprehenderit ... esse cillum *dolor*e eu fugiat ...
在学期之前和之后有两个(或多个)单词。
到目前为止,我有这个
search - .*?(\w+?\b\s){2}(dolor)(\w+?\b\s){2}.*?
replace - ... $1*$2*$3...
但它没有完全奏效;它只能在前后找到一个单词(尽管有{2}),当搜索字符串位于字符串(或句子)的开头或结尾时失败,并且在最终找到的实例之后不会删除段落的其余部分搜索字符串。
最好的方法是什么?
谢谢!
答案 0 :(得分:1)
一些变化:
((\w+\b\s*){2})(dolor)(\w*\s*(\w+\b\s*){2})
...$1*$3*$4...
首先,在这两种情况下,{2}
乘数都需要包含在内存中,以确保您记住这两个单词。这意味着我们可以在阅读时忽略$2
($5
现在包含匹配的最后一个单词。)
其次,在“dolore”和其他任何与dolor \ w +的情况下,终端'e'本身就成了一个单词;为了符合上面的规范,我添加了\ w * \ s *来捕获剩余部分中的任何字尾字符和终端空格。
否则,非贪婪的“?”这里并不真的需要char,因为你已经在\ w +的末尾指定了\ b,所以我也清理了它们。
答案 1 :(得分:0)
关于只匹配一个单词的问题:
来自PHP PCRE文档
当捕获子模式是 重复,捕获的值是 与最终匹配的子字符串 迭代。
e.g。
String
"tweedledum tweedledee"
Regex
(tweedle[dume]{3}\s*)+
Captured value
tweedledee
这个正则表达式可以让你更近一点。
.*?(\w+\b\s*\w+\b\s*)?(dolor)(\w*\s*\w+\b\s*\w+\b)?.*?
对于结尾或字符串开头的dolor不起作用。不处理非空格或非单词字符。不处理彼此跟随的多个dolor实例的问题(例如dolor dolor dolor)。当dolor处于“2个字响”时(例如Lorem ipsum dolor amet dolor),不处理。我现在想不到的其他可能的特殊情况也是unhandeld: - )
答案 2 :(得分:0)
它在开头/结尾失败,因为您指定(或至少尝试指定...)匹配必须包含前导和尾随上下文的两个单词。如果你的“dolor”是第一个单词,那么它就没有了,所以匹配失败了。将{2}
更改为{0,2}
应修复该部分。
另一件立即脱颖而出的事情就是你使用\w+?\b\s
。你可能意味着\w*\b\s
。 *
表示“匹配零或更多”,这相当于您尝试使用+?
指定的“可选匹配一个或多个”。另请注意,除非您将\s
更改为\s+
,否则对于由多个空格分隔的单词,它将失败。标点符号或其他字符也可能存在问题,既不是单词也不是空白字符。
但最后,我认为正则表达可能不是你想要完成的最好的方法,或者至少不是靠自己的方法。最有效的方法可能是构建一个自定义全文搜索,其反向索引包含单词的文本,它的位置(所以你可以按正确的顺序得到它们),以及上下文中突出显示的单词(所以你可以将这些连接在一起以获得最终结果。)
如果那不是一个选项,我会把文本分成几个单词,然后扫描你的目标单词。这不仅可以更轻松地处理您的上下文需求,我预计它也会比纯正则表达式解决方案运行得更快,因为它会严重降低回溯的潜在需求。 (OTOH,虽然,在文本上运行了两次传递(第一次传递将其分成一个单词数组,第二次传递以将每个单词与您的搜索项进行比较)可能会以另一种方式提示。)