Php 正则表达式用于过滤具有挑战性的字符串,包括破折号、空格、数字和某些单词
对于我的搜索面板,我必须过滤一个如下所示的刺:Php 正则表达式用于过滤具有挑战性的字符串,包括破折号、空格、数字和某些单词,php,regex,preg-replace,Php,Regex,Preg Replace,对于我的搜索面板,我必须过滤一个如下所示的刺: '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,ааа,аа 破折号(不超过一个且从不在字符串开头,从不-10kyu或从不-10) 空格(不超过一次,但绝不在字符串开头) 我曾想过这样的事情,但从来没有对我完全起作用:
'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
,ааа
,аа
李>
-10kyu
或从不-10
)李>
/([1-9]| 10)\s-\s|dan|kyu|||||||||/i
编写这种正则表达式的正确方法是什么
编辑1:
无效示例:
4dan\uuuuuuu-\uuuuuu 7kyu
或\u4dan\uuuu7kyu
有效示例:
4dan-7kyu
和4dan-7kyu
和4 dan-7kyu
和4 dan-7kyu
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
向武术同仁致意 如果我很了解您的要求,您可以尝试以下正则表达式:
'((?!(?:[^'\s]*\s[^'\s]*){2,}'|(?:[^'-]*-[^'-]*){2,}')(?:(?:[1-9]|10)\s?-?(?:dan|kyu|дан|кью)?-?)*)'
^(?:(?:[1-9]|10)(?![0-9])) ?(?:(?:dan|kyu|дан|кью) ?)?(?:-? ?(?:(?:[1-9]|10)(?![0-9])) ?(?:(?:dan|kyu|дан|кью) ?)?)*$
开头的负向前看确保字符串中没有两个或更多空格或破折号
然后,在匹配组中使用可能的组合,并捕获所有内容以获得不带引号的字符串。您还可以使用“向前看”和“向后看”来避免捕获
(?<=')(?!(?:[^'\s]*\s[^'\s]*){2,}'|(?:[^'-]*-[^'-]*){2,}')(?:(?:[1-9]|10)\s?-?(?:dan|kyu|дан|кью)?-?)*(?=')
您只需对正则表达式稍加修改即可:
/((10|[1-9])(\s?-?\s?)(dan|kyu|дан|кью)?(\s?-?\s?)(([10|[1-9])(\s?-?\s?)(dan|kyu|дан|кью)?)?)/i
这将使用原始正则表达式,但使数字和dan或kyu之间的空格和连字符可选,然后有另一个可选的空格和连字符,然后可选地重复
我还交换了[1-9]| 10部分,以阻止它抓住1继续前进
\b(?<!-)(10|[1-9])(?: ?(dan|kyu|дан|кью))?(?: ?- ?(10|[1-9])(?: ?(dan|kyu|дан|кью))?)?\b
当然,按照你自己的规则
4-7
是无效的(规则4)?我猜他的意思是你不应该让两个空格字符相邻。但是\s-\s
应该还可以。请添加一些有效和无效字符串的示例。Jerry,非常好,但是匹配4dan-7kyu
并且不带引号(只是示例)@IliaRostovtsev是整个字符串4dan-7kyu
?如果是这样,您可以完全删除引号并使用锚定,方法是将^
放在开头,将$
放在结尾。此外,此字符串将不匹配,因为其中有2个空格。@IliaRostovtsev Awesome!:D@IliaRostovtsev没关系,我不得不早点离开去吃午饭,在这段时间里看不到你的评论,所以这很公平。:)我在您的示例中发现了另一个错误:D.如果您键入11dan-11kyu
,那么它就可以了,但是如果您去键入10dan-11kyu
,那么它就可以在不允许的情况下继续执行;)有趣的示例,但如果您输入$rgData=['12','20dan']代码>这没有什么区别,你的例子让它通过,当它不应该@IliaRostovtsev-是的,没有提到^
和$
。更具体地说,增加了不同的案例。谢谢。好多了,谢谢!!但是它不允许有效的条目,即1kyu-4kyu
或1kyu-4kyu
。你能把它修好让它也匹配吗?还有,如果可能的话,不要删除\u 1kyu-4kyu
只要把它放在那里,但格式化成1kyu-4kyu
@IliaRostovtsev这是一种秘密的dzen regex技术:哇!我对阿尔玛说的话你说得对!太棒了,哦!!工作100%精确!!哦,你的例子真是太美了!谢谢你们所有人,谢谢你们的精彩回答!!如果可以的话,我会接受你所有的3个答案,但由于阿尔玛是第一个提供真正有效示例的人,我将不得不接受阿尔玛的答案!
$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);