对于我的搜索面板,我必须过滤一个看起来像的刺痛
'4dan-7kyu' or '4dan - 7kyu' or '10kyu' or '10 kyu' or '2dan' or '2 dan' or '4-7' or '4 - 7' or '10'
只允许:
1-10
中的数字- 不区分大小写的单词包括:
dan
、kyu
、дан
、кью
- 短划线(不超过一个AND,从不在字符串开头,从不
-10kyu
或从不-10
) - 空格(不超过一次,但从不在字符串开头)
我曾想过这样的事情,但它从未完全适用于我:
/([1-9]|10)'s-'s|dan|kyu|дан|кью/i
什么是正确的方式来榨干这样的Regex?
编辑1:
- 空格(不超过一次,但从不在字符串开头)
无效示例:4dan___-___7kyu
或_4dan_-_7kyu
有效示例:4dan-7kyu
和4dan - 7kyu
以及4 dan - 7kyu
和4 dan - 7 kyu
编辑2:
更多无效示例:12dan-7kyu
或12dan-11kyu
我想那是:
/(^([1-9]|10)'s*$)
|
(^([1-9]|10)'s?-'s?([1-9]|10)'s*$)
|
(^([1-9]|10)'s?(dan|kyu|дан|кью)'s*$)
|
(^([1-9]|10)'s?(dan|kyu|дан|кью)'s?-'s?([1-9]|10)'s?(dan|kyu|дан|кью)'s*$)/ixu
以下是PHP示例:
$rgData = ['12', '20dan', ' 1kyu - 4kyu ', '1kyu - 4kyu ',
'1 kyu - 4 kyu', '1 kyu-4 kyu','4dan-7kyu', '4dan - 7kyu',
'10kyu', '10 kyu', '2dan', '2 dan', '4-7', '4 - 7', '10'];
$sPattern = '/(^([1-9]|10)'s*$)
|
(^([1-9]|10)'s?-'s?([1-9]|10)'s*$)
|
(^([1-9]|10)'s?(dan|kyu|дан|кью)'s*$)
|
(^([1-9]|10)'s?(dan|kyu|дан|кью)'s?-'s?([1-9]|10)'s?(dan|kyu|дан|кью)'s*$)/ixu';
var_dump(array_filter($rgData, function($sItem) use ($sPattern)
{
return preg_match($sPattern, $sItem, $rgMatches);
}));//first 3 not matched
附言:问候武术同事!
如果我很了解您的需求,您可以尝试以下regex:
'((?!(?:[^''s]*'s[^''s]*){2,}'|(?:[^'-]*-[^'-]*){2,}')(?:(?:[1-9]|10)'s?-?(?:dan|kyu|дан|кью)?-?)*)'
查看regex101 上的演示
开头的负先行检查确保字符串中没有两个或多个空格或破折号。
然后,只需在匹配组中有可能的组合,并捕获所有内容即可获得不带引号的字符串。您也可以使用先行和后向来避免捕获。
(?<=')(?!(?:[^''s]*'s[^''s]*){2,}'|(?:[^'-]*-[^'-]*){2,}')(?:(?:[1-9]|10)'s?-?(?:dan|kyu|дан|кью)?-?)*(?=')
编辑:
根据更新,您也许可以尝试以下regex:
^(?:(?:[1-9]|10)(?![0-9])) ?(?:(?:dan|kyu|дан|кью) ?)?(?:-? ?(?:(?:[1-9]|10)(?![0-9])) ?(?:(?:dan|kyu|дан|кью) ?)?)*$
'b(?<!-)(10|[1-9])(?: ?(dan|kyu|дан|кью))?(?: ?- ?(10|[1-9])(?: ?(dan|kyu|дан|кью))?)?'b
查看捕获
我创建了上面的regex,但它不太可读,所以如果你把它放在代码中,你可以让"下一个家伙"更容易理解它(我注意到你有preg-replace
作为标签,所以我假设是PHP):
$numbers = '(10|[1-9])';
$words = '(dan|kyu|дан|кью)';
$seperators = ' ?- ?';
$regex =
'~'b'.
'(?<!-)'.
$numbers.
'(?:'.
' ?'.
$words.
')?'.
'(?:'.
$seperators.
$numbers.
'(?:'.
' ?'.
$words.
')?'.
')?'.
''b~';
$string = "'12dan-7kyu' or '12dan-11kyu' or '_4dan_-_7kyu' or '4 dan - 7kyu' or '4 dan - 7 kyu' or '4dan___-___7kyu' or '4dan-7kyu' or '4dan - 7kyu' or '10kyu' or '10 kyu' or '2dan' or '2 dan' or '4-7' or '4 - 7' or '10' ";
preg_match_all($regex, $string, $out, PREG_SET_ORDER);
看它跑
您只需要在RegEx中稍作修改即可:
/((10|[1-9])('s?-?'s?)(dan|kyu|дан|кью)?('s?-?'s?)(([10|[1-9])('s?-?'s?)(dan|kyu|дан|кью)?)?)/i
这使用了原始的RegEx,但在数字和dan或kyu之间的空格和连字符是可选的,然后又有很多可选的空格和连字符,然后可选地重复。
我还交换了[1-9]|10部分,以阻止它抓住1并继续前进。