preg_match_all特殊条件下的子域

时间:2015-03-20 01:35:39

标签: php regex preg-match-all subdomain

更新

我正在使用这个正则表达式:

/[^a-z^-^0-9^@^%^\/^:^\.^-]((?<!w\.)(?!w+\.)([0-9a-z][0-9a-z\-]*\.){2,}[a-z]+)(["|\s|<]|$)/i

当字符串只是域而没有其他内容时,正则表达式有一点问题,在新行中列在彼此之下

例如:

$string = 'sub84.example4.com
sub-example.example84.net
sub-84example.example-h1.org
www-example4124.domain.com
sub.example-www.com';

所有域名都应匹配,但他目前的正则表达式仅匹配sub-example.example84.netwww-example4124.domain.com

我还希望增加一些条件:

1)域名信件必须很小并且不能是资本(当前人不关心这一点) EX:Sub.example.Com不行。

2)在域之前没有=SPACE (SPACE (" :SPACE,而SPACE)SPACE= ") {{1}在它之后。

EX:

SPACE:

没有一个没问题

3)排除$string = ' text = sub1.example.com text text ( sub2.example.com text text sub3.example.com = text text sub4.example.com ) text text ("sub5.example.com text text sub6.example.com") text text : sub7.example.com text text sub8.example.com : text '; .info .biz tlds

谢谢。

3 个答案:

答案 0 :(得分:3)

我不太了解这样做的目的或者令人难以置信的条件,但你可能会尝试这个(相当长的......):

(?<!http://)(?<!https://)(?<!www\.)(?![^\s<>]*[:@/])(?<![(=:] )(?<!\(")(?:(?<=[\s">])|^)(?:[a-z0-9-]+\.){2}(?!info|biz|tv)[a-z]+(?=[\s"<]|$)(?! [=):])(?!"\))

regex101 demo


故障:

(?<!http://)(?<!https://)(?<!www\.)        # Prevent http:// https:// and www.
(?![^\s<>]*[:@/])                          # Prevent : @ /
(?<![(=:] )(?<!\(")                        # Prevent '( ' '= ' etc
(?:(?<=[\s">])|^)                          # Ensure there's ' ', '>', '"' or beginning of line
(?:[a-z0-9-]+\.){2}(?!info|biz|tv)[a-z]+   # Main match, alphanumerics and -, 2 parts + tlds (excluding info, biz, tv
(?=[\s"<]|$)                               # Ensure there's ' ', '<', '"' or end of line
(?! [=):])(?!"\))                          # Prevent ' )' ' =' etc

答案 1 :(得分:2)

随着正则表达式的出现,前瞻和后视是昂贵的。你可以在没有这种怪物的情况下做到这一点:

(?:^[^0-9a-zA-Z]??|[^=(:][^0-9a-zA-Z\-]|=[^ 0-9a-zA-Z]|\([^ "0-9a-zA-Z]|:[^ 0-9a-zA-Z]|[^0-9a-zA-Z]-)((?:[0-9a-z][0-9a-z\-]*\.){2,}(?:[ac-hj-su-z][a-z]*|b[a-z]?|bi[a-y]|b[a-z]{3,}|i[a-z]{0,2}|inf[a-np-z]|i[a-z]{4,}|t|t[a-uw-z]|t[a-z]{2,}))(?:[^a-zA-Z "]| [^=:)]|"[^)]|[ "]?$)

这将按 1 强制执行小写子域,正确删除您在 2 中列出的所有前置和后置条件,并禁止 .biz 3 的em>, .info .tv

但是您需要将其与m修饰符一起使用,以便^$可以匹配每行而不仅仅是输入的开头和结尾。因此,您需要执行以下操作:

preg_match_all('/(?:^[^0-9a-zA-Z]??|[^=(:][^0-9a-zA-Z\-]|=[^ 0-9a-zA-Z]|\([^ "0-9a-zA-Z]|:[^ 0-9a-zA-Z]|[^0-9a-zA-Z]-)((?:[0-9a-z][0-9a-z\-]*\.){2,}(?:[ac-hj-su-z][a-z]*|b[a-z]?|bi[a-y]|b[a-z]{3,}|i[a-z]{0,2}|inf[a-np-z]|i[a-z]{4,}|t|t[a-uw-z]|t[a-z]{2,}))(?:[^a-zA-Z "]| [^=:)]|"[^)]|[ "]?$)/m', $string, $foo);

让我快速解释一下正则表达式的各个部分,这有希望有意义:

第一部分是对子域之前的内容的替代,它可以防止您在 2 中列出的前置条件:(?:^[^0-9a-zA-Z]??|[^=(:][^0-9a-zA-Z\-]|=[^ 0-9a-zA-Z]|\([^ "0-9a-zA-Z]|:[^ 0-9a-zA-Z]|[^0-9a-zA-Z]-)它是非捕获的将匹配6个选项中的1个的组:

  1. 一行的开头,可能还有一个非字母数字字符
  2. '=''('':'以外的字符,后跟非字母数字非'-'字符
  3. '='后跟非空格和非字母数字字符
  4. '('后跟'"',空格或字母数字以外的字符
  5. A ':'后跟非空格和非字母数字字符
  6. 非字母数字字符后跟'-'字符
  7. 捕获中的第二部分是原始子域减去后缀匹配:(?:[0-9a-z][0-9a-z\-]*\.){2,}

    第三部分也在捕获内部,消除了具有"biz""info""tv"个修正的子域:(?:[ac-hj-su-z][a-z]*|b[a-z]?|bi[a-y]|b[a-z]{3,}|i[a-z]{0,2}|inf[a-np-z]|i[a-z]{4,}|t|t[a-uw-z]|t[a-z]{2,})它是非捕获的有10个选项的小组:

    1. 'b''i''t'以外的字符后跟任意数量的小写字符
    2. 一个'b'和一些其他小写字符
    3. "bi"后跟非'z'字符
    4. 'b'后跟3个或更多小写字符
    5. 'i'后跟2个或更少的小写字符
    6. "inf"后跟非'o'字符
    7. 'i'后跟4个或更多小写字符
    8. 't'个字符
    9. 't'后跟非'v'字符
    10. 一个't'后跟两个或多个小写字符
    11. 最后一部分可以防止您在 2 中列出的后置条件:(?:[^a-zA-Z "]| [^=:)]|"[^)]|[ "]?$)它是一个非捕获组,有4个选项:

      1. 不是空格,'"',小写或大写字符的字符
      2. 后跟除'='':'')'
      3. 以外的字符的空格
      4. '"'后跟非')'字符
      5. 非空格非 - '"'后跟行尾

答案 2 :(得分:0)

这是

/[^a-z^-^0-9^@^\/^:^\.^-]((?<!w\.)(?!w+\.)([0-9a-z][0-9a-z\-]*\.)+[a-z]+)(["\s<]|$)/ig