我正在尝试编写一个替换正则表达式来包围引号中的所有单词,但单词AND,OR和NOT除外。
我已经尝试了以下表达式的匹配部分:
(?i)(?<word>[a-z0-9]+)(?<!and|not|or)
和
(?i)(?<word>[a-z0-9]+)(?!and|not|or)
但是没有工作。替换表达式很简单,目前包含所有单词。
"${word}"
所以
这和这不是
成为
“这个”和“这个”不是“那个”
答案 0 :(得分:14)
这有点脏,但它有效:
(?<!\b(?:and| or|not))\b(?!(?:and|or|not)\b)
用简单的英语,这匹配任何不在前面的词边界,而不是“and”,“或”或“not”。它仅匹配整个单词,例如单词“sand”之后的位置不会是匹配,因为它前面是“and”。
零宽度后视断言中“或”前面的空间对于使其成为固定长度的后视是必要的。如果这已经解决了您的问题,请尝试。
编辑:应用于字符串“除了单词AND,OR和NOT。”作为单引号的全局替换,它返回:
'except' 'the' 'words' AND, OR and NOT.
答案 1 :(得分:5)
约翰,
你问题中的正则表达式几乎是正确的。唯一的问题是你将前瞻放在正则表达式的末尾而不是开头。此外,您需要添加单词边界以强制正则表达式匹配整个单词。否则,它将匹配“和”中的“nd”,“或”等中的“r”,因为“nd”和“r”不在您的负向前瞻中。
\ B(Ⅰ')(与|△!不|或)(?[A-Z0-9] +)\ B'/ P>
答案 2 :(得分:3)
MatchEvaluator
:
string[] whitelist = new string[] { "and", "not", "or" };
string input = "foo and bar or blop";
string result = Regex.Replace(input, @"([a-z0-9]+)",
delegate(Match match) {
string word = match.Groups[1].Value;
return Array.IndexOf(whitelist, word) >= 0
? word : ("\"" + word + "\"");
});
(编辑更简洁的布局)
答案 3 :(得分:2)
根据Tomalaks回答:
(?<!and|or|not)\b(?!and|or|not)
这个正则表达式有两个问题:
(?<! )
仅适用于固定长度的后视
以前的正则表达式仅查看周围单词的结尾/开头,而不是整个单词。
(?<!\band)(?<!\bor)(?<!\bnot)\b(?!(?:and|or|not)\b)
这个正则表达式修复了上述两个问题。首先将后视分为三个独立的后视镜。其次是在环顾中添加单词边界(\b
)。
答案 4 :(得分:0)
(?!\bnot\b|\band\b|\bor\b|\b\"[^"]+\"\b)((?<=\s|\-|\(|^)[^\"\s\()]+(?=\s|\*|\)|$))
我使用此正则表达式查找不在双引号内的所有单词,或者单词“not”“和”或“或”。
答案 5 :(得分:0)
要匹配由字母,数字或下划线(包括\w
shorthand character class中定义的任何其他单词字符)组成的任何“单词” ,您可以使用单词边界喜欢
\b(?!(?:word1|word2|word3)\b)\w+
如果“单词”是一大堆非空白字符,并且两端都是字符串的开头/结尾或空白,请使用空白边界,如
(?<!\S)(?!(?:word1|word2|word3)(?!\S))\S+
这两个表达式看起来像
\b(?!(?:and|not|or)\b)\w+
(?<!\S)(?!(?:and|not|or)(?!\S))\S+
请参见regex demo(或流行的regex101 demo,但请注意,PCRE \w
的含义不同于.NET \w
的含义。)
模式说明
\b
-word boundary (?<!\S)
-向后查找的否定字符,匹配的位置不是紧随空格以外的其他字符,它需要字符串位置的开始或空白字符位于当前位置的正前方(?!(?:word1|word2|word3)\b)
-如果在当前位置的右侧紧邻有word1
,word2
或word3
个char序列,则负匹配将使匹配失败单词边界(或,如果使用(?!\S)
空格右边界,则必须在当前位置的右边紧接空格或字符串结尾)\w+
-1+ word chars \S+
-除whitespace以外的1个以上的字符在C#和任何其他编程语言中,您可以通过将数组/列表项与管道字符(下面的see the demo)连接起来,来动态构建模式:
var exceptions = new[] { "and", "not", "or" };
var result = Regex.Replace("This and This not That",
$@"\b(?!(?:{string.Join("|", exceptions)})\b)\w+",
"\"$&\"");
Console.WriteLine(result); // => "This" and "This" not "That"
如果您的“单词”可能包含特殊字符,则使用空格边界方法更为合适,并确保使用exceptions.Select(Regex.Escape)
来转义“单词”:
var pattern = $@"(?<!\S)(?!(?:{string.Join("|", exceptions.Select(Regex.Escape))})(?!\S))\S+";
注意:如果要搜索的单词过多,则最好用它们构建一个 regex trie 。