我想编写一个正则表达式(我正在使用MATLAB),它会找到序列'a'但拒绝整个字符串包含隔离字符'x'的情况,即'x'(包括空格)其中'x'用作a和b)的分隔符。
以下是我能想到的几个例子。
答案 0 :(得分:2)
有趣的问题。我将添加一些测试用例,我认为这些测试用例是为了明确指出问题所必需的。希望这是你的意图。
测试数据:
s = {'a', ... %// match
'a b', ... %// match
'b a', ... %// match
'a x b', ... %// don't
'b x a', ... %// don't
'a xb', ... %// match
'ab', ... %// don't match
'ba' ... %// don't match
} ;
正则表达式:
ind = cellfun(@(x) ~isempty(regexp(x,'^a(?=\s)|(?<=\s)a$|^a$|(?<=\s)(a)(?=\s)')),s) ...
& cellfun(@(x) isempty(regexp(x,'(?<=\s)x(?=\s)')),s)
ind =
1 1 1 0 0 1 0 0
>> s(ind)
ans =
'a' 'a b' 'b a' 'a xb'
解释:
查找包含x
的字符串,其中匹配前面有一个空格((?<=\s)
),后跟一个空格((?=\s)
。排除这些。
查找以a
后跟空格(^a(?=\s)
)开头的字符串,或以a
开头且前面有空格((?<=\s)a$
)的字符串,或者正好是a
而没有其他字符(^a$
),或者包含a
的字符前后都有空格((?<=\s)(a)(?=\s)
)。匹配这些。
答案 1 :(得分:1)
让我们借用@transversality条件的测试用例并添加一些额外内容:
s = {'a', ... %// match
'a b', ... %// match
'b a', ... %// match
'a x b', ... %// don't
'b x a', ... %// don't
'a xb', ... %// match
'ab', ... %// don't match
'ba', ... %// don't match
'x a', ... %// don't match
'a x' ... %// don't match
} ;
此解决方案根本不使用外观。相反,它使用anchors:
ind = cellfun(@(x) ~isempty(regexp(x, '\<a\>', 'once')), s) ...
& cellfun(@(x) isempty(regexp(x,'\<x\>', 'once')), s)
这只找到包含a
的字符串,其中a
位于单词的开头和结尾(并且单词是连续的字母数字字符序列),并且不包含孤立的{{1} }。
与@ tc的测试相反,最后两个案例与此测试不匹配(但也许他们应该?OP没有指定......)。
答案 2 :(得分:0)
如果你正在使用Matlab,那么你有比正则表达更好的选择。但如果你坚持,你可以使用lookarounds:
(?<!.\bx\b.)a(?!.\bx\b.)