我想要一个正则表达式,如果它在字符串中有3个.
个实例,那么它会做一件事,如果它有3个以上的实例则需要其它的东西。
例如
aaa.bbb.ccc.ddd // one part of the regex
aaa.bbb.ccc.ddd.eee // the second part of the regex
如何在js
或c#
?
类似
?(\.){4} then THIS else THAT
在正则表达式中...
更新
好吧基本上我正在做的是这个:
我想将任何给定的System.Uri
切换到扩展方法中的另一个子域。
我遇到的问题是我的域名通常为http://subdomain.domain.TLD.TLD/more/url
,但有时候,它只能是http://domain.TLD.TLD/more/url
(只指www
)
所以这就是我想出来的:
public static class UriExtensions
{
private const string TopLevelDomainRegex = @"(\.[^\.]{2,3}|\.[^\.]{2,3}\.[^\.]{2,3})$";
private const string UnspecifiedSubdomainRegex = @"^((http[s]?|ftp):\/\/)(()([^:\/\s]+))(:([^\/]*))?((?:\/)?|(?:\/)(((\w+)*\/)([\w\-\.]+[^#?\s]+)(\?([^#]*))?(#(.*))?))?$";
private const string SpecifiedSubdomainRegex = @"^((http[s]?|ftp):\/\/)(([^.:\/\s]*)[\.]([^:\/\s]+))(:([^\/]*))?((?:\/)?|(?:\/)(((\w+)*\/)([\w\-\.]+[^#?\s]+)(\?([^#]*))?(#(.*))?))?$";
public static string AbsolutePathToSubdomain(this Uri uri, string subdomain)
{
subdomain = subdomain == "www" ? string.Empty : string.Concat(subdomain, ".");
var replacement = "$1{0}$5$6".FormatWith(subdomain);
var spec = Regex.Replace(uri.Authority, TopLevelDomainRegex, string.Empty).Distinct().Count(c => c == '.') != 0;
return Regex.Replace(uri.AbsoluteUri, spec ? SpecifiedSubdomainRegex : UnspecifiedSubdomainRegex, replacement);
}
}
基本上使用此代码我会使用System.Uri
和:
subdomain.domain.TLD.TLD
属性{/ 1}}。Authority
或.XX[X]
结尾的任何内容).XX[X].XX[X]
或domain
subdomain.domain
,因为我无法弄清楚如何使用UnspecifiedSubdomainRegex
告诉它如果该部分没有点,它应该返回SpecifiedSubdomainRegex
我的问题是,是否有办法将这三个正则表达成合并为更简单的
PD:忘了javascript,我只是用它来动态测试正则表达式
答案 0 :(得分:14)
您可以使用(?(?=condition)then|else)
构造执行此操作。但是,这在JavaScript中不可用(但它在.NET,Perl和PCRE中可用):
^(?(?=(?:[^.]*\.){3}[^.]*$)aaa|eee)
例如,将检查一个字符串是否包含正好三个点,如果是,它会尝试匹配字符串开头的aaa
;否则它会尝试匹配eee
。所以它将匹配
aaa.bbb.ccc.ddd
eee.ddd.ccc.bbb.aaa
eee
但失败
aaa.bbb.ccc
eee.ddd.ccc.bbb
aaa.bbb.ccc.ddd.eee
<强>解释强>
^ # Start of string
(? # Conditional: If the following lookahead succeeds:
(?= # Positive lookahead - can we match...
(?: # the following group, consisting of
[^.]*\. # 0+ non-dots and 1 dot
){3} # 3 times
[^.]* # followed only by non-dots...
$ # until end-of-string?
) # End of lookahead
aaa # Then try to match aaa
| # else...
eee # try to match eee
) # End of conditional
答案 1 :(得分:1)
^(?:[^.]*\.[^.]*){3}$
上面的正则表达式将匹配正好有3个点的字符串--- http://rubular.com/r/Tsaemvz1Yi。
^(?:[^.]*\.[^.]*){4,}$
和这一个 - 对于有4个点或更多点的字符串--- http://rubular.com/r/IJDeQWVhEB
答案 2 :(得分:1)
在Python中(对不起;但正则表达式没有语言边界)
import re
regx = re.compile('^([^.]*?\.){3}[^.]*?\.')
for ss in ("aaa.bbb.ccc",
"aaa.bbb.ccc.ddd",
'aaa.bbb.ccc.ddd.eee',
'a.b.c.d.e.f.g.h.i...'):
if regx.search(ss):
print ss + ' has at least 4 dots in it'
else:
print ss + ' has a maximum of 3 dots in it'
结果
aaa.bbb.ccc has a maximum of 3 dots in it
aaa.bbb.ccc.ddd has a maximum of 3 dots in it
aaa.bbb.ccc.ddd.eee has at least 4 dots in it
a.b.c.d.e.f.g.h.i... has at least 4 dots in it
此正则表达式模式不要求分析整个字符串(其中没有符号$)。在长琴弦上效果更好。
答案 3 :(得分:0)
你不需要正则表达式(和许多其他常见任务一样)。
public static string AbsolutePathToSubdomain(this Uri uri, string subdomain)
{
// Pre-process the new subdomain
if (subdomain == null || subdomain.Equals("www", StringComparison.CurrentCultureIgnoreCase))
subdomain = string.Empty;
// Count number of TLDs (assume at least one)
List<string> parts = uri.Host.Split('.').ToList();
int tldCount = 1;
if (parts.Count >= 2 && parts[parts.Count - 2].Length <= 3)
{
tldCount++;
}
// Drop all subdomains
if (parts.Count - tldCount > 1)
parts.RemoveRange(0, parts.Count - tldCount - 1);
// Add new subdomain, if applicable
if (subdomain != string.Empty)
parts.Insert(0, subdomain);
// Construct the new URI
UriBuilder builder = new UriBuilder(uri);
builder.Host = string.Join(".", parts.ToArray());
builder.Path = "/";
builder.Query = "";
builder.Fragment = "";
return builder.Uri.ToString();
}