[Question]
  [
Your task is to write a program or function that checks if a string is a valid phone number.
Given a string (or list of characters/codepoints) input, you will output a truthy value if the input is a valid phone number. If it is not, output a falsey value. An input string is considered a valid phone number for this challenge if it meets all of these criteria:
* It contains ten digits, which are grouped like this: `###-###-####`
* The strings separating the digit groups must be the same
* The first and last characters must be part of the phone number (i.e. must not be part of a separator)
Test cases:
```
111-222-3333     truthy
123-456-7890     truthy (number groups can contain different numbers)
1112223333       truthy (can have 0 length separators)
111022203333     falsey (has more than 10 numbers)
111ABC222ABC3333 truthy (can have length>1 separators)
111-222_3333     falsey (non-matching separators)
111-22-23333     falsey (missing digit in middle group)
111--222--33333  falsey (extra digit in last group)
-111-222-3333    falsey (first character is not part of number)
111-222-3333a    falsey (last character is not part of number)
aaa-aaa-aaaa     falsey (not enough numbers)
11-2222-3333     falsey (wrong separator location)
111-1-222-1-3333 falsey (too many numbers)
```
This is a code golf challenge, shortest answer per language wins.
  
[Answer]
# [Jelly](https://github.com/DennisMitchell/jelly), 22 [bytes](https://github.com/DennisMitchell/jelly/wiki/Code-page)
```
fØDȯ0ṁ334DR¤jḟØDŒHḢƊµƑ
```
A monadic Link accepting a list of characters which yields `1` if it is a valid telephone number and `0` otherwise.
**[Try it online!](https://tio.run/##y0rNyan8/z/t8AyXE@sNHu5sNDY2cQk6tCTr4Y75QLGjkzwe7lh0rOvQ1mMT////b2ZgUpRYlmpsYAyiLIyNLQA "Jelly – Try It Online")** Or see a [test-suite](https://tio.run/##jZIxS8NAFMf3fooHDrVgIEmdBbWDs6uIPNNL7srlUu5e1Y66CG46uQniKDgJdW1p8WvULxIvae3FNoIPkuFefv//vf9Lj0k5zPN48tj5fPPnH9ft9m7nePzSm4@e7Nn04Wg@ep7djd9n9/nk9uvmNc9PmkEQeGEYem1bTShrC0gPiA8bO0XXNis914XtCBVwvGDgg2QqIQ6G9VEjZdq0FrBvaf@XdIzSMAtzNJBmmgFxKxP4oAbpOVuB@weHFrXvJVzjuvDcCzZdi4HOal1VprwUKeJCJbWcF9ZyqTCmQLoiEQRCQSq6Xckg0dmg/0OXOZZBlgKOZlek0bESDTnS29yAI2Oh7bcRt/eMiGkQBlRGYO9NkMXLzCpTlyK4rlIa/kMEV1XZtotuMUEBr0VnAW/5YPNv7lJs/CIrH1dVkso9IQFK2WqcfgM "Jelly – Try It Online").
### How?
```
fØDȯ0ṁ334DR¤jḟØDŒHḢƊµƑ - Link: list of characters, S  e.g. '123a456bc78de'
                     Ƒ - is S invariant under...
                    µ  - ...this function of S?:
f                      -   filter keep:
 ØD                    -     digit characters              '12345678'
   ȯ0                  -   OR zero (necessary as ṁ will error with an empty list)
           ¤           -   nilad followed by link(s) as a nilad:
      334              -     literal 334                   334
         D             -     to decimal                    [3,3,4]
          R            -     range (vectorises)            [[1,2,3],[1,2,3],[1,2,3,4]]
     ṁ                 -   mould (left) like (right)       ['123','456','7812']
                   Ɗ   -   last three links as a monad  - i.e. f(S):
             ḟ         -     filter discard:
              ØD       -       digit characters           'abcde'
                ŒH     -     split in halves              ['abc', 'de']
                  Ḣ    -     head (zero if empty)         'abc'
            j          -   join                           '123abc456abc7812'
                                                  (...not invariant as not equal to S)
```
[Answer]
# Perl, 36 bytes
```
print/^\d{3}(\D*)\d{3}\1\d{4}$/?1:0
```
Run as
```
perl -ne 'print/^\d{3}(\D*)\d{3}\1\d{4}$/?1:0' <<< "111-222-3333"
```
[Try it online!](https://tio.run/##K0gtyjH9/78ASCno5qUqqBcUZeaV6MfFpFQb12rEuGhpglkxhkDKpFZF397QykBdwcbGRkHJ0NBQ18jISNcYCJT@//9vZmBSlFiWamxgDKIsjI0tAA "Perl 5 – Try It Online")
[Answer]
# [APL (Dyalog Unicode)](https://www.dyalog.com/), ~~30~~ 29 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319 "When can APL characters be counted as 1 byte each?")[SBCS](https://github.com/abrudz/SBCS ".dyalog files using a single byte character set")
```
'^\d{3}(\D*)\d{3}\1\d{4}$'⎕S⍬
```
It simply `⎕S`earches for the PCRE regex and returns a dummy value (the empty numeric list) for each match. If none are found, it returns a single empty numeric list.
[Try it online!](https://tio.run/##SyzI0U2pTMzJT///Xz0uJqXauFYjxkVLE8yKMQRSJrUq6o/6pgY/6l3zP@1R24RHvX1Arqf/o67mQ@uNH7VNBEkGOQPJEA/P4P9p6oaGhrpGRka6xkCgzgXmA7lIPAMg1wCJ7@jkDBQBkkhiIBPiUfm6yGbogq0A2wEW0sViK5yfqA4A "APL (Dyalog Unicode) – Try It Online") The effect of printing a list of empty lists is to print two spaces on a line, while the effect of printing an empty list is to print an empty line. Select all contents in the Output field to reveal the spaces, or use [this](https://tio.run/##SyzI0U2pTMzJT///qG9qsCuQCA9Wdy1LzStRV1APTi0uzszPCyjKBHOdcxKLMtMq1bmgjEdtE6qBGoCU@qO2Seo6QCVAbpD6oe3qj3qnPurdVftfPS4mpdq4ViPGRUsTzIoxBFImtSoglcGPetf8TwNqf9TbB@R6@j/qaj603vhR20SQZJAzkAzx8Az@n6ZuaGioa2RkpGsMBOpcYD6Qi8QzAHINkPiOTs5AESCJJAYyIR6Vr4tshi7YCrAdYCFdLLbC@YnqAA "APL (Dyalog Unicode) – Try It Online") to lead each printed line with `→` and each space with `·`.
[Answer]
# [05AB1E](https://github.com/Adriandmen/05AB1E/wiki/Commands), 16 [bytes](https://github.com/Adriandmen/05AB1E/wiki/Codepage)
```
þ©м2äн®T∍ƵêS£sýQ
```
Port of [*@JonathanAllan*'s Jelly answer](https://codegolf.stackexchange.com/a/195319/52210).  
Thanks to *@Grimy* for fixing a bug.
[Try it online](https://tio.run/##yy9OTMpM/f//8L5DKy/sMTq85MLeQ@tCHnX0Htt6eFXwocXFh/cG/v9vaGjo6ORsZGQEJI0B) or [verify all test cases](https://tio.run/##yy9OTMpM/V9TVmmvpPCobZKCkn3l4Qn/D@87tPLCHqPDSy7sPbQu5FFH77Gth1cFH1pcfHhv4P8Enf@Ghoa6RkZGusZAwAXkANkwpqOTM5AHJGECBkCuAYwD0hWPxNGF69MFGwg20ZhLF90COCcRxFNwNHRSAIqAabCSxMREXShORHUFAA).
**Explanation:**
```
þ                 # Only leave the digits of the (implicit) input-string
 ©                # Store it in variable `®` (without popping)
  м               # Remove all digits from the (implicit) input-string
   2ä             # Split the remaining characters into two equal-sized parts
     н            # And only leave the first part
      ®           # Push the digits from variable `®` again
       T∍         # Extend this string of digits to size 10
         Ƶê       # Push compressed integer 334
           S      # Converted to a list of digits: [3,3,4]
            £     # And split the digits of the input into parts of that size
             s    # Swap to get the earlier string
              ý   # And join the digit-parts with this delimiter-string
               Q  # Check if it's now equal to the (implicit) input-string
                  # (after which the result is output implicitly)
```
[See this 05AB1E tip of mine (section *How to compress large integers?*)](https://codegolf.stackexchange.com/a/166851/52210) to understand why `Ƶê` is `334`.
[Answer]
# [PHP](https://php.net/), 50 bytes
Just a simple regex, with a backreference to make sure the separator is the same.
```
<?=preg_match('/^\d{3}(\D*)\d{3}\1\d{4}$/',$argn);
```
[Try it online!](https://tio.run/##VU3bCoJAEH3frwgR1GjQ2bUbFtGFvmJJBhPtIV3Mt/DX27Y1wwbmcs6ZOaNKpfVmt1VNXqR3arPS98KLvD5F58vTNLCTRNPizg29mUtNUQWJzrOynjiychKNiMA5B2GCIRcQzxewXK0jZhQj9DxiZOZoAPvD0UBTB@JjkY4A/O7Ault7weD/2wgQIyL4JrFeGe31m2iJV63aW109NJzf "PHP – Try It Online")
[Answer]
# JavaScript (ES6), 37 bytes
```
s=>/^\d{3}(\D*)\d{3}\1\d{4}$/.test(s)
```
[Try it online!](https://tio.run/##hZLbTsMwDIbveQprQmqL1PUwbjeJg3gC7lZAoU2boDapYncCoT17cTvQylSGL5LI8v/5lDexE5g73VJobCH7ct3jehM9Z8Xnau9n91fB@MoSvq73l9GSJJKPQZ9bg7aWy9pWvrd9dB2pjycvuJj6S3@RJEmYpmm4YlsEAQw2E8Mh0wiAKIJcGFBiJyGGWpqKFKBshRNkHc4gbm7vmMLnD2iKOAA2yRTxi@FlZvsgavyjh5jR8bRChiuB0FgngRSnSWIwXfMqZ2sbRvByIjfWhI2gXGlTne@M1WF6om404iAsdKUJtGFHUdQSKme7do4xbmFcwwHDDPlOThwJtUCa14czW2R9qR0rcsWV5yQdaOSmCLgTAlt@j@PchxBH1pj8H1T/BQ "JavaScript (Node.js) – Try It Online")
[Answer]
# [Gema](http://gema.sourceforge.net/), 26 characters
```
<D3><-d><D3>$2<D4>\Z=t
*=f
```
There is no truthy / falsey concept in Gema, so just outputting “t” / “f”.
Sample run:
```
bash-5.0$ echo -n 111-222-3333 | gema '<D3><-d><D3>$2<D4>\Z=t;*=f'
t
```
[Try it online!](https://tio.run/##S0/NTfz/38bF2M5GN8UORKsY2biY2MVE2ZZwadmm/f9vaGioa2RkpGsMBAA "Gema – Try It Online") / [Try all test cases online!](https://tio.run/##lZHBTsJAEIbP7FOMTWXBZANdPCHbiOLBk4lHS0PWdmuJ2DbdJdGgz15mW0SFcrBJZyb55p/5p32WOq1iFa1kqYBNwShtFpHUSvRIJ6Ce5zHOORvhQ0NBTbk26QfdISTtYIhk@I0SudJqj6Y3twgxtivttkW7EhHjJ1BtsnZ5SNnhCUdDGyQPmJSS7V55JLOqkxObmd4R7hNSlMvMJEA/4ZzxoQabvb@ZY5xnFOh9VqwN5kel1ytb3L0XKjIqxvLhlRKS5CUsbRNGcNzN2f7fBdfhl3MFcU46Za0WjtsDFaU5MNtaqxzcNsgLM3hRb3Kgy6gugFaT2cifsNi32eWT2aU/fxKGXIikotB3COn844z9MsdtrNhq8@O0wWgXrMUg@NUnRGvreOxhdxhCt9ucZL@G9RXnmaq2 "Bash – Try It Online")
[Answer]
# [Ruby](https://www.ruby-lang.org/) `-n`, 28 bytes
Same as basically every other regex solution here. Note that in Ruby, `0` is actually truthy. (Only `false` and `nil` are falsey in Ruby)
```
p~/^\d{3}(\D*)\d{3}\1\d{4}$/
```
[Try it online!](https://tio.run/##hZHbTsMwDIbveQpLIG1MlB7GNRKHR@CyAmWt1wS1SRU7aBMaj05xu65DGxJR0iSWv/7Obx9W247CCuKcbhfxDcxmcAkv2hDIfA/EwA6o8JLiglw0Am5aLBhL8EihZurar/g1Lz@Xu3n@vLgeTnkq293uKu66NE2jLMuipQzoB/vAenshcQlP0UMc5oWyoNUHQgI12oo1ELbKK3aernssES6ZwLWqCQXTiqBxHqVG@UGagA3NCkfk4fFJIPkO2JnSXuc@PVXqC387U7LORo3iQhtb/UFE2RnRGKI@uTSVYTAWGlOWNULlXWj33ODRYNLyyOGGvTpStZJ@jEx06uuBWRsvWYWWqqRLvu@jdQxSJYNbj65Mrxtw9ZsfRP7FlVLRuNSJOQxoXaj01IBv17JxlrrI/gA "Ruby – Try It Online")
[Answer]
# [Red](http://www.red-lang.org), 64 bytes
```
func[s][d: charset[#"0"-#"9"]parse s[3 d copy t to d 3 d t 4 d]]
```
[Try it online!](https://tio.run/##Zc@7DoMgFAbguT7FH5xJvHSpW@sbdCWkIVxih6pBHPr0FLAXtSeBwEfOyY/Vyl@1YjwzjTdzL9nEmWogO2En7VhOCkJzciJ8jICJ1VCQw/iEgxvCOd4djlCcezNYLWSHfn6AkbIsaVVVtA5FkB0QK2rAZCsqghV7PF/awGFfHrCuz/Tbvikg/RtPU5CU5Od0E3A7YkHxVSEEfS9BOBhGe@8dTPoqh38B "Red – Try It Online")
As always [Red](http://www.red-lang.org)'s `parse` is much longer than regex.
[Answer]
# [Python 3](https://docs.python.org/3/), ~~69~~ ~~66~~ 57 bytes
```
lambda n:re.match(r"\d{3}(\D*)\d{3}\1\d{4}$",n)
import re
```
[Try it online!](https://tio.run/##K6gsycjPM/6fZhvzPycxNyklUSHPqihVLzexJDlDo0gpJqXauFYjxkVLE8yKMQRSJrUqSjp5mlyZuQX5RSUKRan/C4oy80o00jSUDA0NdY2MjHSNgUBJU5MLWQIojk3Y0ckZKAMksUkaAKUMsEmAbInHIaGL1R5dsMPALkOV08XnaLhEIlDmPwA "Python 3 – Try It Online")
Thanks To:  
-@Arnauld and @Value Ink for saving me 3 bytes by using match instead of fullmatch  
-@Value Ink for saving me another 6 bytes
[Answer]
# [Java (JDK)](http://jdk.java.net/), 43 bytes
```
s->s.matches("\\d{3}(\\D*)\\d{3}\\1\\d{4}")
```
[Try it online!](https://tio.run/##bU7LasMwELznKxZDwA6RsJ2ekjbQx7UlEOilDmVjK4lcv5DWgRL87aps16lbKlhpZnd2RimekaXJh5F5VSqC1HJek8z4oS5ikmXBZ6tJnKHW8IyygMsEoKr3mYxBE5J9zqVMILczd0tKFse3HaA6aq@TAmyUSGSMJG778RqkfsVMJptTWYiXOt8LBXdGs7XmOVJ8Etp1oii5LBo3ip5mXo@jKGjBTeN4ZtUZH0rlnlFB9eOz/JUMsP3UJHJe1sQrm00H15mGvl7CVE8LZz5enf/zLU5CkzsSeV4f3UzaaowJgoCFYcgW9rTE4gH6FvsDuX94tNTeQ6Pdeh8Rdt1jnWHnuDDsb8CVoEFE9l1o@slI1yuDrvEF "Java (JDK) – Try It Online")
Apparently I came to the same solution as others: a simple regex is the key.
[Answer]
# [Retina 0.8.2](https://github.com/m-ender/retina/wiki/The-Language/a950ad7d925ec9316e3e2fb2cf5d49fd15d23e3d), 24
Same regex as the other regex-based answers:
```
^\d{3}(\D*)\d{3}\1\d{4}$
```
[Try it online!](https://tio.run/##K0otycxL/K@q4Z7wPy4mpdq4ViPGRUsTzIoxBFImtSr//xsaGuoaGRnpGgMBF5ADZMOYBkC2AYzj6OQM5AJJmABIVzwSRxeuTxdsINhEYy5ddAvgnESuxMREXShOVAAA "Retina 0.8.2 – Try It Online")
[Answer]
# [Kotlin (JDK)](https://kotlinlang.org), 60 bytes
```
{s: String->s.matches(Regex("\\d{3}(\\D*)\\d{3}\\1\\d{4}"))}
```
[Try it online!](https://tio.run/##bU5dS8MwFH3frwiFQiJL6YdPooNtPos48CkgV5d2wTYdSSqO0t8ek9SOIF644Zybe865n71phbT1IFEHQmJQjb5DW6Xgcn8wSshmQ9C4Qq6@oEVCv0Irjs@nXvKnoXvnCj0gOzrJvEw3OuvAfJy4xi@84d84Yew4VhNm7PGGzJixwoPbKSFkssG77hXC58hVSORPWbJ9HS7a8C7rB5OdXZapcZKWuYtOdSqTNYrk638Oje0JCa7TarK2KApaliWtXHni8AJzh/OFbHd7R927DLzqLSL0qqPBMDhWlv4NuBKwAEB/G@z8E@3Nm0UY/AA "Kotlin – Try It Online")
Really similar to the Java one
[Answer]
# [Clojure](https://clojure.org/), 46 bytes
```
(fn[x](re-matches #"\d{3}(\D*)\d{3}\1\d{4}"x))
```
[Try it online!](https://tio.run/##S87JzyotSv2vkZKappD2XyMtL7oiVqMoVTc3sSQ5I7VYQVkpJqXauFYjxkVLE8yKMQRSJrVKFZqa/zW5NAqKMvNKcvIUNNIUlAwNDXWNjIx0jYFASRNd0shY18TUTNfcwtIAU9LQEKgRuz5DQwOgnAEuSUcnZ6A0kMSlAOSkeDySujjt1QX7BuwdTHld/L5FkkzEkE1MTNSF4kQsWkE68ZgLMdkQpuA/AA "Clojure – Try It Online")
Another day, another regex.
[Answer]
# [SimpleTemplate](https://github.com/ismael-miguel/SimpleTemplate), 56 bytes
This was actually a very simple challenge, using [XMark](https://codegolf.stackexchange.com/users/88635/xmark)'s RegEx in the [PHP answer](https://codegolf.stackexchange.com/a/195367/).
```
{@ifargv.0 is matches"@^\\d{3}(\\D*)\\d{3}\\1\\d{4}$@"}1
```
Sadly, due to the need to escape the slashes, this code is 5 bytes longer :/
This code outputs 1 in case the input matches (truthy), or nothing (falsy).
You can try the golfed and ungolfed versions in <http://sandbox.onlinephpfunctions.com/code/ca206ad7cc82351283e6c319ce5f9ae03f87b695>  
You can also check the generated PHP code, if you are curious.
[Answer]
# [QuadS](https://github.com/abrudz/QuadRS), ~~28~~ 25 [bytes](https://codegolf.meta.stackexchange.com/a/9429/43319 "When can APL characters be counted as 1 byte each?")[SBCS](https://github.com/abrudz/SBCS ".dyalog files using a single byte character set")
```
^\d{3}(\D*)\d{3}\1\d{4}$
```
It simply `⎕S`earches for the PCRE regex and returns a dummy value (the empty string) for each match. If none are found, it returns a single empty numeric list.
[Try it online!](https://tio.run/##KyxNTCn@/z8uJqXauFYjxkVLE8yKMQRSJrUqXP//GxoZ6@qamJrp6pqZW5gDAA "QuadS – Try It Online") The effect of printing a list of empty strings is to print two spaces on a line, while the effect of printing an empty list is to print an empty line. Select all contents in the Output field to reveal the spaces, or use [this](https://tio.run/##KyxNTCn@r/6obZK6jrqC@qO@qUHqh7arP@qd@qh36/@4mJRq41qNGBctTTArxhBImdSqcP3/b2hkrKtrYmqmq2tmbmEOAA "QuadS – Try It Online") to lead the printed line with `→` and each space with `·`.
]