【问题标题】:Regex for ANY string except "www"? (subdomain)除“www”外的任何字符串的正则表达式? (子域)
【发布时间】:2016-09-22 17:20:55
【问题描述】:

我想知道是否有人可以帮助我使用 C# 中的正则表达式。我认为这很简单,但我一直在为它绞尽脑汁,不太清楚为什么我会遇到这样的困难。 :)

我发现了一些例子,但我似乎无法操纵它们来做我需要的事情。

我只需要匹配任何不是“www”的字母数字+破折号子域字符串,直到“。”

另外,理想情况下,如果有人输入“www.subdomain.domain.com”,我希望尽可能忽略 www。如果不是,这不是一个大问题。

也就是说,我想匹配:

  • (测试).domain.com
  • (test2).domain.com
  • (wwwasdf).domain.com
  • (asdfwww).domain.com
  • (w).domain.com
  • (wwwwww).domain.com
  • (asfd-12345-www-bananas).domain.com
  • www.(子域).domain.com

我不想匹配:

  • (www).domain.com

在我看来这应该很容易,但我在“不匹配”部分遇到了麻烦。

对于它的价值,这是用于 IIS 7 URL 重写模块,为所有非 www 子域重写。

谢谢!

【问题讨论】:

  • 你知道如何完全匹配所有你想要的字符串吗?提示:如果你这样做了,你的问题就解决了,只需围绕匹配反转你的布尔逻辑。

标签: c# asp.net regex string rewrite


【解决方案1】:

域名的其余部分是否是常量,如.domain.com,如您的示例中所示?试试这个:

\b(?!www\.)(\w+(?:-\w+)*)(?=\.domain\.com\b)

解释:

  • \w+(?:-\w+)* 匹配您描述的通用域名组件(但更严格一些)。

  • (?=\.domain\.com\b) 确保它是第一个子域(即实际域名之前的最后一个子域)。

  • \b(?!www\.) 确保它不是www.(没有\b,它可以跳过第一个w 并仅匹配ww.)。

在我的测试中,此正则表达式与您在示例中突出显示的部分完全匹配,并且 匹配最后两个示例中的 www.


编辑:这是与全名匹配的另一个版本,将片段捕获在不同的组中:

^((?:\w+(?:-\w+)*\.)*)((?!www\.)\w+(?:-\w+)*)(\.domain\.com)$

在大多数情况下,组$1 将包含一个空字符串,因为在子域名之前没有任何内容,但它是如何分解www.subdomain.domain.com

$1: "www."
$2: "subdomain"
$3: ".domain.com"

【讨论】:

  • 我认为您需要将 ?= 换成 ?: ,然后它可以在 regexplanet.com/simple/index.html 中使用。我不熟悉 ?= - 也许它仅在某些引擎上受支持。如果您还在开始和结束时使用 ^ 和 $,那么它比我的答案更好..
  • 我不想匹配整个 URL,只是匹配示例中突出显示的部分。这就是为什么我在那里使用lookahead,以及为什么我没有使用锚点(^$)。
  • 艾伦,感谢您的回复。这似乎非常适合匹配,但我不确定如何对子域进行分组以进行替换。我的正则表达式有点弱。你有什么想法吗?
  • 我实际上最终选择了这个,它似乎工作正常,除了 www.sub.domain.com,这现在很好。非常感谢您的指导!! ^\b(?!www\.)(\w+(?:-\w+)*)(?:\.example\.com)$
  • @trnelson:看看我的编辑;您可能会发现正则表达式更易于使用。
【解决方案2】:
^www\.

并反转该位的逻辑,因此如果匹配,则您的字符串不符合您的要求。

【讨论】:

  • 这并没有涵盖 OP 列出的所有情况。
  • 这仍然没有涵盖所有列出的案例(特别是wwwwww.domain.comwwwasdf.domain.com)。
  • @Oli 好点,现在我已经确保正则表达式检查它是否以 . 结尾。
【解决方案3】:

这行得通:

^(?!www\.domain\.com)(?:[a-z\-\.]+\.domain\.com)$

或者,为 Java(或 C#?)字符串使用必要的反斜杠:

"^(?!www\\.domain\\.com)(?:[a-z\\-\\.]+\\.domain\\.com)$"

可能有一种更简洁的方式(即只输入一次 domain.com),但这可行..

【讨论】:

    【解决方案4】:

    只需用 www 之后的所有内容替换原始内容(如果存在)(伪代码):

    str = re.sub("(www\.)?(.+)", "\2", str)
    

    或者,如果您只想匹配那些“错误”的,请使用:

    (www\.([^.]+)\.([^.]+))
    

    如果你必须匹配所有好的,使用这个:

    (([^w]|w[^w]|ww[^w]|www[^.]|www\.([^.]+)\.([^.]+)\.).+)
    

    【讨论】:

    • 这个不匹配wwwasdf.domain.com
    • @Mrchief:确实如此,它在替换中被单独留下。
    【解决方案5】:

    在这里大声思考:

    ^(?:www\.)?([^\.]+)\.([^\.]+)\.
    

    在哪里...

    • (?:www\.)?在开始时寻找可能的“www”,非捕获
    • ([^\.]+)\.查找子域(除了点之外的任何内容,直到点为止至少一次)
    • ([^\.]+)\.查找以点结尾的域(除了点之外的任何内容,至少出现一次直到点为止)

    注意:此表达式不适用于双子域: www.subsub.sub.domain.com

    【讨论】:

    • 有点像这个想法,这是我到目前为止想出的:(?:www\.)?(?:www)?([\w\-]*) \.example\.com 这似乎适用于:www.subdomain.example.com。但似乎仍然不适用于:www.example.com。
    【解决方案6】:

    这个:

    ^(?:www\.)?([^.]*)
    

    它与您在问题中括号中的内容完全匹配。您将在组 (1) 中找到您的答案。您必须将其锚定到行首。使用这个:

    ^(?:www\.)?(.*)    
    

    如果您想要 URL 中除“www.”之外的所有内容。您没有在测试用例中包含的一个示例是“alpha.subdomain.domain.com”。如果您需要匹配除“www.”之外的所有内容,即不在字符串的“domain.com”部分中,请使用:

    ^(?:www\.)?(.+)((?:\.(?:[^./\?]+)){2})
    

    它将解决您的所有案例,但此外,还将从我的附加测试案例中返回“alpha.subdomain”。并且,对于安可,将“.domain.com”放在第 2 组中,如果 url 中有目录或参数,则不会匹配。

    我验证了所有这些回复here

    最后,为了矫枉过正,如果你想拒绝以“www.”开头的地址,你可以使用否定的lookbehind:

    ^....(?<!www\.).*
    

    【讨论】:

    • 太棒了,谢谢迈克尔。今晚当我跳回代码时,我会试一试! :)
    【解决方案7】:

    我想我会分享这个。

    (\\.[A-z]{2,3}){1,2}$
    

    从末尾删除任何“.com.au”“.co.uk”。然后,您可以进行额外的查找以检测 URL 是否包含子域。

    例如

    subdaomin1.sitea.com.au
    subdaomin2.siteb.co.uk
    subdaomin3.sitec.net.au

    全部变成:

    subdomain1.sitea
    subdomain2.siteb
    subdomain3.sitec

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多