如何仅提取包含子域的URL

时间:2018-08-18 13:08:10

标签: regex linux search grep

我的原始文件包含:

mail.google.com
srv1.mail.google.com
google.com
facebook.com
yahoo.com
tt.twitter.com
yy.notexist

我想提取包含子域的行。哪些是

mail.google.com
srv1.mail.google.com
tt.twitter.com

我尝试过此正则表达式:

grep -P '^.[^.]+\.(.[^.])+\..[^.]+$' test.csv

但是它仅给出:

mail.google.com

我不知道为什么看不到其余的内容。我不确定我的正则表达式是否完美并能捕获所有情况。我不确定如何使用正则表达式表达^.[^.]来表达(除点以外的任何字符)。你能纠正我吗?

4 个答案:

答案 0 :(得分:3)

基于给定样本输入/输出的答案,没有智能来区分什么是顶级域

$ awk -F. 'NF>2 || $NF!="com"' ip.txt
mail.google.com
srv1.mail.google.com
tt.twitter.com
yy.notexist

$ # any domain, not just .com
$ awk -F. 'NF>2' ip.txt
mail.google.com
srv1.mail.google.com
tt.twitter.com
  • -F.设置.作为输入字段分隔符
    • 某些版本可能需要-F'[.]'而不是-F.
  • NF>2 || $NF!="com"打印行,如果它有两个以上的字段,或者最后一个字段不是com


使用grep

$ grep -xv '[^.]*\.com' ip.txt
mail.google.com
srv1.mail.google.com
tt.twitter.com
yy.notexist

$ # any domain, not just .com
$ grep -xv '[^.]*\.[^.]*' ip.txt
mail.google.com
srv1.mail.google.com
tt.twitter.com
  • -x仅匹配整行
  • -v打印与给定正则表达式不匹配的行
  • [^.]*个非.个字符
  • \.com以匹配.com

答案 1 :(得分:2)

您可以使用以下表达式:

^(?:(?:[a-z0-9]+.){2,}com|[a-z0-9]+(?!.com).[a-z]+)$

正则表达式明细:

  • ^字符串的开头。
  • (?:非捕获组。
    • (?:[a-z0-9]+\.){2,}com非捕获组,匹配小写字母或数字,后跟句号。重复图案两次或更多次。之后匹配com
    • |替代,或。
    • [a-z0-9]+(?!\.com)\.[a-z]+小写字母或数字,后跟.com,后跟.和字母字符。
  • )关闭非捕获组。
  • $字符串结尾。

命令:

grep -P '^(?:(?:[a-z0-9]+\.){2,}com|[a-z0-9]+(?!\.com)\.[a-z]+)$' test.csv

打印:

mail.google.com
srv1.mail.google.com
tt.twitter.com
yy.notexist

编辑:

根据您的修改,使用:

^(?:[a-z0-9]+.){2,}com$

命令:

grep -P '^(?:[a-z0-9]+\.){2,}com$' test.csv

打印:

mail.google.com
srv1.mail.google.com
tt.twitter.com

答案 2 :(得分:0)

您只得到1个匹配项,因为您的正则表达式将匹配3个由2个点分隔的部分,因此不匹配:

srv1.mail.google.com
google.com
facebook.com
yahoo.com

您不匹配tt.twitter.com,因为这部分(.[^.])+\.会捕获一组重复一次或多次匹配单个字符的组,而不是一个点,该点每次重复匹配2个字符用文字点表示。

例如,这将不匹配twitter.,因为它包含7个字符和一个点,并且重复是每2个,因此twitte.将匹配。

您似乎不希望匹配至少由2个点分隔的点。如果要使模式[^.]+不匹配点,则可以使用:

grep -P '^[^.]+(?:\.[^.]+){2,}$' test.csv

这将匹配:

  • ^声明字符串的开头
  • [^.]+一次或多次不匹配点
  • (?:\.[^.]+){2,}非捕获组,该组至少重复2次与文字点匹配,然后不匹配一个或多个点
  • $声明字符串的结尾

答案 3 :(得分:-2)

我可以通过以下命令达到我的问题所发布的要求:

    @SuppressWarnings("unused")
        @JavascriptInterface
        public String processHTML(final String html)
        {
//            Log.i("processed html",html);
            Thread OauthFetcher=new Thread(new Runnable() {

                @Override
                public void run() {

                    htmlString= Html.fromHtml(html).toString();
//                    Log.i("htmlString",htmlString);
                    Gson gson = new Gson();
                    CustomPojoObject obj = gson.fromJson(htmlString, CustomPojoObject.class);

                }
            });OauthFetcher.start();
            return htmlString;
        }

这是一个简单的命令,用于标识带有多个点的URL,这意味着它们具有子域。但是,这不能区分uni.ac.uk是主域还是子域。理想情况下,使用具有更多高级技术的一个库来进行处理的另一阶段,以便从具有多个点的URL中识别出主域。这些库的一个示例是tldextract