您可以使用\bp(?:i|\w*(?>\h+\w+)*?\h+i)(?:t|\w*(?>\h+\w+)*?\h+t)(?:y|\w*(?>\h+\w+)*?\h+y)
的模式來匹配這些單詞。它假定空格被用作單詞分隔符。這是相當容易構建,只需要匹配您的詞的第一個字母,然後循環其他人,並從他們構建(?:[letter]|\w*(?>\h+\w+)*?\h+[letter])
。
此模式基本上是\bp(?:i|.*?\bi)(?:t|.*?\bt)(?:y|.*?\by)
的展開版本,它將倒數第二個字母視爲下一個字的下一個字母或第一個字母(由於字邊界)。
你可以看到它在這裏的行動:https://regex101.com/r/r3ZVNE/2
我已經添加了最後一個樣本爲不匹配的一個用於一些測試我的原子團一樣。
在Delphi中我會做這樣的:
program ProjectTest;
uses
System.SysUtils,
RegularExpressions;
procedure CheckSpecialMatches(const Matchword: string; const CheckList: array of string);
var
I: Integer;
Pat, C: string;
RegEx: TRegEx;
begin
assert(Matchword.Length > 0);
Pat := '\b' + Matchword[1];
for I := Low(Matchword) + 1 to High(Matchword) do
Pat := Pat + Format('(?:%0:s|\w*(?>\h+\w+)*?\h+%0:s)', [Matchword[I]]);
RegEx := TRegEx.Create(Pat, [roCompiled, roIgnoreCase]);
for C in CheckList do
if Regex.IsMatch(C) then
WriteLn(C);
end;
const
CheckList: array[0..3] of string = (
'pious teddy',
'piston tank yard',
'pesky industrial strength tylenol',
'prison is ity');
Matchword = 'pity';
begin
CheckSpecialMatches(Matchword, CheckList);
ReadLn;
end
。
整潔! 「展開」和未展開版本有什麼區別? '(?:\ h + \ w +)*?\ h + i)'vs'(?:i |。*?\ bi)' – user124114
@ user124114基本上'(?> \ h + \ w +)*?'逐字逐字逐句,而'。*?'逐字逐字地逐字。由於原子組的原因,它還可以減少回溯。 –