神奇的电子邮件转换!或者:帮助NSA从您的电子邮件地址中提取您的元数据


17

给定一个电子邮件地址,应用于该电子邮件地址的转换结果以及第二个电子邮件地址,将返回应用于第二个电子邮件地址的相同转换的输出。

电子邮件地址都将具有以下结构:

一串正长度的字符串,包含字母数字字符和最多一个.(局部部分),后跟一个@符号,然后是一串正长度的字符串,其中包含字母数字sumbols(域),后跟一个.符号,最后是一串正长度的字符串包含字母数字字符(TLD)。

有四个允许的转换:

  • 身份(不变)。(a.b@c.d -> a.b@c.d
  • 仅返回本地部分(之前的所有内容) @未修改(a.b@c.d -> a.b))。
  • 返回本地部分拆分 .如果存在),并用大写的每半个符号表示。(a.b@c.d -> A B)。
  • 仅返回域(介于@和最终之间的所有内容.未修改)。(a.b@c.d -> c)。

如果可能进行多个转换,则可以给出任何可能性的输出。输出开头和结尾的空格无关紧要,但是中间的空格就无关紧要(即,如果拆分a.bA B中间,则中间应该只有一个空格[并且输出的开头和结尾应该是空格),但是如果拆分a.,那么A在任何一侧都可以有任意数量的空格)。

范例(input | output):

john.doe@gmail.com, John Doe, phillip.maini@gmail.com         | Phillip Maini
John.Doe@gmail.com, John Doe, Phillip.Maini@gmail.com         | Phillip Maini
foo.bar@hotmail.com, foo.bar, gee.whizz@outlook.com           | gee.whizz
foo.bar@hotmail.com, foo.bar, gEe.Whizz@outlook.com           | gEe.Whizz
rodney.dangerfield@comedy.net, comedy, michael.scott@office.0 | office
.jones@x.1, Jones, a.@3.z                                     | A
.jones@x.1, .jones@x.1, a.@3.z                                | a.@3.z
.jones@x.1, .jones, a.@3.z                                    | a.
.jones@x.1, x, a.@3.z                                         | 3
.@b.c, .@b.c, 1@2.3                                           | 1@2.3
john.jones@f.f, John Jones, 1in.thehand@2inthe.bush           | 1in Thehand
chicken.soup@q.z, Chicken Soup, fab@ulou.s                    | Fab
lange@haare.0, lange, fat.so@fat.net                          | fat.so
Lange@haare.0, Lange, fat.so@fat.net                          | {fat.so, Fat So} # either acceptable
chicken@chicken.chicken, chicken, horse@pig.farm              | {horse, pig} # either acceptable

通常存在规则和漏洞。


最后一个测试用例不应该返回“马”吗?我不明白为什么它可以返回“猪”。
Erik the Outgolfer

3
@EriktheOutgolfer,因为第四个转换将仅返回域(介于@和final 之间的部分.)。由于本地部分和领域都相同chicken,因此是第二次转换还是第四次转换都
不清楚

哦,我误解了。
Erik the Outgolfer '17

我们是否可以在所有情况下都要求相关输入的格式为空格(例如,在测试中输出为A[带尾随空格]的情况下,第二个输入为Jones[带前导空格])?
乔纳森·艾伦

我不明白为什么.jones@x.1, Jones, a.@3.zA-如果jones匹配这意味着匹配的部分是第一期和@符号之间的部分。但是,这将导致一个空字符串,因为该字符串a在第一个句点之前而不是之后。
杰里·耶利米

Answers:


4

爪哇8,254个 240 236字节

(a,b,c)->{String A[]=a.split("@"),C[]=c.split("@"),x="";for(String p:C[0].split("\\."))x+=(p.charAt(0)+"").toUpperCase()+p.substring(1)+" ";return a.equals(b)?c:A[0].equals(b)?C[0]:A[1].split("\\.")[0].equals(b)?C[1].split("\\.")[0]:x;}

-4个字节,感谢@LukeStevens

说明:

在这里尝试。

(a,b,c)->{                  // Method with three String parameters and String return-type
  String A[]=a.split("@"),  //  Split `a` by "@" into two parts
         C[]=c.split("@"),  //  Split `c` by "@" into two parts
         x="";              //  Temp-String
  for(String p:C[0].split("\\.")) 
                            //  Loop over the first part of `c`, split by dots
    x+=                     //   Append String `x` with:
       (p.charAt(0)+"").toUpperCase()
                            //    The first character as uppercase
       +p.substring(1)      //    + the rest of the String
       +" ";                //    + a space
                            //  End of loop (implicit / single-line body)
  return a.equals(b)?       //  If input `a` and `b` are exactly the same:
    c                       //   Return `c`
   :A[0].equals(b)?         //  Else-if the first part of `a` equals `b`:
    C[0]                    //   Return the first part of `c`
   :A[1].split("\\.)[0].equals(b)?
                            //  Else-if the domain of `a` equals `b`
    C[1].split("\\.)[0]     //   Return the domain of `c`
   :                        //  Else:
    x;                      //   Return String `x`
}                           // End of method

1
您可以使用(p.charAt(0)+"").toUpperCase()代替删除4个字节Character.toUpperCase(p.charAt(0))
卢克·史蒂文斯

@LukeStevens谢谢!(char)(p.charAt(0)&~32)起初我有,但是由于1in Thehand测试用例,这没有用。但是将其大写为String确实比短Character.toUpperCase,所以谢谢!
凯文·克鲁伊森

3

Haskell,208个字节

import Data.Char
s c""=[]
s c a=w:f t where
 (w,t)=span(/=c)a
 f(_:y)=s c y
 f _=[]
h=head
u""=""
u(x:y)=toUpper x:y
l=h.s '@'
f x y=h[t|t<-[id,l,unwords.filter(/="").map u.s '.'.l,h.s '.'.last.s '@'],t x==y]

在线尝试!

很遗憾,我不得不花费59个字节来重塑splits)。

该解决方案创建一个转换列表,并返回导致预期结果的第一个转换。


欢迎光临本站!我不知道Haskell,但是是否可以删除任何空白字符,例如换行符和空格?
caird coinheringaahing

不错的第一答案!您可能会对我们在Haskell打高尔夫球技巧感兴趣,尤其是这个这样可以节省一些字节。
Laikoni '17

也可以随时加入我们的“单子与男人”Of Monads and Men),这是一个聊天室,是打高尔夫球和Haskell的一般讨论区。
Laikoni '17

3

果冻,40 个字节

先发制人感谢Outgolfer的Erik注意到使用失败Œt(标题大小写),因此Œu1¦€K结束了ŒtK

-1字节由于埃里克Outgolfer(重排⁵⁸ç⁹¤Ŀçµ⁵⁸Ŀ


ÑṪṣ”.Ḣ
ṣ”@
ÇḢ
Çṣ”.Œu1¦€K
⁹ĿðЀ5i
çµ⁵⁸Ŀ

一个完整的程序回吐exampleEmailexampleOutputrealEmail和打印结果。

在线尝试!

怎么样?

执行所有四个转换(加上前一个转换),找到第一个从第一封电子邮件中产生示例的转换,然后将其应用于第二封电子邮件:

            - Link 1, do nothing: email
            - do nothing but return the input

ÑṪṣ”.Ḣ      - Link 2, the domain: email
Ñ           - call the next link (3) as a monad (split at "@")
 Ṫ          - tail
  ṣ”.       - split at "."
     Ḣ      - head

ṣ”@         - Link 3, split at @: email
ṣ”@         - split at "@"

ÇḢ          - Link 4, local part: email
Ç           - call the last link (3) as a monad (split at "@")
 Ḣ          - head

Çṣ”.Œu1¦€K  - Link 5, name-ified: email
Ç           - call the last link (4) as a monad (get the local part)
 ṣ”.        - split at "."
       ¦€   - for €ach sparsley apply:
      1     - ...to index: 1
    Œu      - ...action: uppercase
         K  - join with space(s)

⁹ĿðЀ5i     - Link 6, index of first correct link: exampleEmail; exampleOutput
   Ѐ5      - map across (implicit range of) 5 (i.e. for each n in [1,2,3,4,5]):
  ð         -   dyadicly (i.e. with n on the right and exampleEmail on the left):
 Ŀ          -     call referenced link as a monad:
⁹           -     ...reference: chain's right argument, n
      i     - first index of exampleOutput in the resulting list

çµ⁵⁸Ŀ       - Main link: exampleEmail; exampleOutput
ç           -   call the last link (6) as a dyad (get the first "correct" link index)
 µ          - monadic chain separation (call that L)
   ⁸        - chain's left argument, L
    Ŀ       - call the link at that reference as a monad with input:
  ⁵         -   program's third input, realEmail

笔记:

  1. 假设输入exampleOutput与输出严格相同。

  2. 已测试“前体”(链接3的结果)是否与匹配exampleOutput,但除非其exampleOutput本身是字符列表,否则它将不匹配。因此,应避免使用输入引号(此处可使用Python格式)以避免产生这样的解释。




2

JavaScript(ES6),145个字节

使用currying语法调用,例如 f('chicken.soup@q.z')('Chicken Soup')('fab@ulou.s')

x=>y=>[x=>x,s=x=>x.split`@`[0],x=>s(x).split`.`.map(w=>w&&w[0].toUpperCase()+w.slice(1)).join` `.trim(),x=>/@(.+)\./.exec(x)[1]].find(f=>f(x)==y)


1

Mathematica,217个字节

(L=Capitalize;T@x_:=(M=StringSplit)[x,"@"];P@x_:=#&@@T[x];W@x_:=If[StringContainsQ[P@x,"."],StringRiffle@L@M[P@x,"."],L@P@x];Z@x_:=#&@@M[T[x][[2]],"."];If[#==#2,#3,If[#2==P@#,P@#3,If[#2==W@#,W@#3,If[#2==Z@#,Z@#3]]]])&


在线尝试!



1

果酱,42

q~@{[_\'@/~'./0=\_'.%{(eu\+}%S*]}:T~@a#\T=

在线尝试

说明:

q~        read and evaluate the input (given as 3 quoted strings)
@         bring the first string to the top of the stack
{…}:T     define a function T that calculates the 4 transformations of a string:
  [       begin array
  _\      duplicate the string, and swap with the other copy to bring it in the array
           (1st transformation)
  '@/~    split by '@' and put the 2 pieces on the stack
  './0=   split the 2nd piece by '.' and keep the first part
           (4th transformation)
  \_      swap with the piece before '@' and duplicate it
           (2nd transformation)
  '.%     split by '.', removing the empty pieces
  {…}%    transform the array of pieces
    (eu   take out the first character and capitalize it
    \+    prepend it back to the rest
  S*      join the pieces by space
           (3rd transformation)
  ]       end array
~         execute the function on the first string
@a        bring the 2nd string to the top of the stack, and wrap it in an array
#         find the position of this string in the array of transformations
\T        bring the 3rd string to the top and call function T
=         get the transformation from the array, at the position we found before

1

PHP 7.1,176字节

<?$e=explode;[,$p,$q,$r]=$argv;echo$p==$q?$r:($e('@',$p)[0]==$q?$e('@',$r)[0]:($e('.',$e('@',$p)[1])[0]==$q?$e('.',$e('@',$r)[1])[0]:ucwords(join(' ',$e('.',$e('@',$r)[0])))));

在线尝试!

PHP <7.1,180字节

7.1以下的版本需要将更[,$p,$q,$r]=$argv改为list(,$p,$q,$r)=$argv,增加4个字节。


1

GNU sed,105 +1(r标志)= 106字节

前三个s命令分别检查标识本地部分转换。如果一个转换匹配,则将其应用于第二个电子邮件地址,并且s由于缺少输入格式,以下命令将失败。

s:^(.*),\1,::
s:(.*)@.*,\1,(.*)@.*:\2:
s:.*@(.*)\..*,\1,.*@(.*)\..*:\2:
s:.*,([^.]*)\.?(.*)@.*:\u\1 \u\2:

在线尝试!

本地部分分开的转换(最后的s指令)进行检查,以字节为单位的最昂贵的,所以我把它放在年底假定它匹配(因为其他的人到那个时候失败了),直接将其应用。


1

果冻,43个字节

ḢŒlṣ”.Œu1¦€K
ṣ”@Wẋ4j”@$ḷ/ÇṪṣ”.Ḣ$$4ƭ€
Çiị⁵Ǥ

在线尝试!


ŒtK在地方的工作Œu1¦€K,以节省3?
乔纳森·艾伦

...又有什么需要Œl
乔纳森·艾伦,

^啊,我认为那1in.thehand是行不通的ŒtK
乔纳森·艾伦,

@JonathanAllan Yep,这就是我不使用它的原因,也是ovs(现已删除)答案无效的原因(str.title)的原因。
暴民埃里克(Erik the Outgolfer)'17年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.