Що таке регулярний вираз для MAC-адреси?


125

У такому форматі:

3D:F2:C9:A6:B3:4F

або:

3D-F2-C9-A6-B3-4F

Відповіді:


266

Стандартний формат (IEEE 802) для друку MAC-48 адрес у зручній для людини формі - це шість груп з двох шістнадцяткових цифр, розділених дефісами -або двокрапками :.

Так:

^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$

21
Зауважте, що якщо вони зберігаються з малих шістнадцяткових букв, це не відповідає зміні групи на [0-9A-Fa-f], щоб зафіксувати обидва випадки
Скотт Чемберлен

5
ви, ймовірно, також хочете ігнорувати корпус
dietbuddha

5
^ ([0-9A-Fa-f] {2} [: -]) {5} ([0-9A-Fa-f] {2}) $
Раджавель D

2
Окрім того, цитата, що стосується "стандартного формату", походить з Вікіпедії, а не з 802.3. IEEE 802-2014 фактично вказує дефіси для звичайних MAC-адрес (§ 8.1 ¶ 3) та колонки для застарілої бітової нотації (¶ 4). Важливо, що на практиці цього ніхто не зауважує . Ми просто використовуємо те чи інше, але ніколи не змішуємо їх в одному написаному MAC.
pilcrow

1
Я не думаю, що цей RegEx є правильним, оскільки він також класифікує "3D-F2-C9: A6-B3: 4F" як дійсну MAC-адресу, навіть невірна. Правильним було б: ((([a-zA-z0-9] {2} [-:]) {5} ([a-zA-z0-9] {2})) | (([a- zA-z0-9] {2}:) {5} ([a-zA-z0-9] {2}))) Так щоразу ви можете вибрати ":" або "-" для всієї MAC-адреси.
PyFox

23

Трохи важко для очей, але це:

/^(?:[[:xdigit:]]{2}([-:]))(?:[[:xdigit:]]{2}\1){4}[[:xdigit:]]{2}$/

буде застосовувати або всі двокрапки, або всі тире для вашої нотації MAC.

(Більш простий підхід з регулярного виразів може дозволити A1:B2-C3:D4-E5:F6, наприклад, який вищезгадане відкидає.)


Це працює, але чи можете ви пояснити, що таке: xdigit? і я помітив, що ви поставили групу ([-:]) після тривалості, що змушує взяти або всі колонки, або дефіси?
Xaisoft

2
@Xaisoft, :xdigit:короткий шістнадцятковий розряд, більш-менш інший спосіб висловлювання [a-fA-F0-9]. \1Відноситься до групи захоплення для першого тире або двокрапки ([-:]), і відповідає тільки те , що відповідає , що в перший раз.
pilcrow

2
+1 для належного використання як груп захоплення, так і тих, що не захоплюють, а також для використання :xdigit:(хоча ця "стенограма" лише трохи коротша, [a-fA-F0-9]а еквівалент /[a-f0-9]/iкоротша!)
gb96

@pilcrow, чи можете ви поясніть, чому цей mac: C8:FD:19:55:E6:3Aне працює? Це фактична mac-адреса. Я змінив ваш регулярний вираз, щоб прийняти :тільки /^(?:[[:xdigit:]]{2}([:]))(?:[[:xdigit:]]{2}\1){4}[[:xdigit:]]{2}$/Спасибі!
Сем

1
На мій погляд, це краща відповідь, оскільки вона фактично перевіряє змішане використання ":" і "-".
Ray Oei

9

Цей регулярний вираз відповідає майже кожному формату Mac, включаючи формат Cisco, такий як 0102-0304-abcd

^([[:xdigit:]]{2}[:.-]?){5}[[:xdigit:]]{2}$

Приклад рядків, яким він відповідає:

01:02:03:04:ab:cd
01-02-03-04-ab-cd
01.02.03.04.ab.cd
0102-0304-abcd
01020304abcd

Змішаний формат також буде відповідний!


Це буде відповідати роздільникам після будь-якого з перших п’яти октетів, тобто, наприклад, він прийме aa.aa.bbbb.cccc.
pilcrow

1
#notAllFormats Якщо у вас є доступ до системи OSX з WiFi, запустіть /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport -Iі шукайте рядок BSSID, якщо який-небудь октет нижче 0x10 провідний нуль випадає ( %xабо, %2xа не %02x printfвикористовується формат?)
nhed

8

Роздільник: " : ", " - ", " "

подвійний або одинарний: 00 = 0, 0f = f

/^([0-9a-f]{1,2}[\.:-]){5}([0-9a-f]{1,2})$/i

або

/^([0-9a-F]{1,2}[\.:-]){5}([0-9a-F]{1,2})$/


exm: 00:27:0e:2a:b9:aa, 00-27-0E-2A-B9-AA, 0.27.e.2a.b9.aa ...

2
Другий буде неправильно відповідати рядкам, які містять не шістнадцяткові символи, такі як g.
Бінарний Філі

Другий недійсний у більшості ароматів, за винятком BRE / ERE, який підтримує діапазон символів. Однак підтримка співставлення діапазону символів відрізняється між реалізацією, тому результат може відрізнятися.
nhahtdh

Інша справа, що групи повинні мати рівно 2 шестизначні цифри.
nhhtdh

Теоретично всі mac-адреси, що повертаються програмами в дикій природі, дотримуватимуться деяких стандартних, наприклад 2-х шістнадцяткових цифр у кожній окремій групі. Однак деякі нестандартизовані варіанти Unix вкорочують вихід, коли є первинний нуль, залишаючи лише 1 шістнадцятковий знак у деяких випадках. Звідси потреба у {1,2}регулярному вираженні
TrinitronX

Однак набір символів, [0-9a-F]мабуть, слід переписати як:[0-9a-fA-F]
TrinitronX

5

Попереджуйте, що властивість Unicode \p{xdigit}включає версії FULLWIDTH. Ви можете \p{ASCII_Hex_Digit}замість цього віддати перевагу .

Відповідь на поставлене запитання може бути найкращим чином відповісти - за умови встановлення певного поважного модуля CPAN - ввівши:

% perl -MRegexp::Common -lE 'say $RE{net}{MAC}'

Я показую конкретний зразок, який він виводить тут як вдалий шаблон №13; є багато інших.

Ця програма:

#!/usr/bin/env perl
use 5.010;
use strict;
use warnings qw<FATAL all>;

my $mac_rx = qr{
    ^ (?&MAC_addr) $
    (?(DEFINE)
        (?<MAC_addr>
                (?&pair) (?<it>  (?&either) )
            (?: (?&pair) \k<it> ) {4}
                (?&pair)
        )
        (?<pair>    [0-9a-f] {2} )
        (?<either>  [:\-]        )
    )
}xi;

while (<DATA>) {
    chomp;
    printf("%-25s %s\n", $_ => /$mac_rx/ ? "ok" : "not ok");
}

__END__
3D:F2:C9:A6:B3:4F
3D:F2:AC9:A6:B3:4F
3D:F2:C9:A6:B3:4F:00
:F2:C9:A6:B3:4F
F2:C9:A6:B3:4F
3d:f2:c9:a6:b3:4f
3D-F2-C9-A6-B3-4F
3D-F2:C9-A6:B3-4F

генерує цей вихід:

3D:F2:C9:A6:B3:4F         ok
3D:F2:AC9:A6:B3:4F        not ok
3D:F2:C9:A6:B3:4F:00      not ok
:F2:C9:A6:B3:4F           not ok
F2:C9:A6:B3:4F            not ok
3d:f2:c9:a6:b3:4f         ok
3D-F2-C9-A6-B3-4F         ok
3D-F2:C9-A6:B3-4F         not ok

Що здається видом речі, яку ви шукаєте.



4

Дивіться це питання .

Реджекси наступним чином:

^[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}$

^[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}$

1
Чи не існує способу скоротити це, роблячи групи? і як я можу поєднати регулярний вираз з a: або a - не маючи 2 окремих регулярних виразів?
Xaisoft

Працює також скорочена форма, яку надає netcoder. Використання одного чи іншого може базуватися на тому, чи потрібно вам захопити якусь MAC-адресу або просто перевірити її в цілому.
JYelton

Його потрібно перевірити в цілому, тому якщо він або містить всі дефіси, або всі двокрапки. Якщо він містить суміш, він не є дійсним MAC.
Xaisoft

2
@Xaisoft: Як я вже говорив у коментарі своєї відповіді, змішування колонок та дефісів є дійсним відповідно до специфікації.
netcoder

З якого джерела ви отримуєте MAC-адреси, які можуть містити розмежувачі? Якщо вони надходять з фактичної машини / NIC, ви, ймовірно, не матимете цієї проблеми. Якщо це введені користувачем дані, просто виконайте заміну рядка, щоб зробити всі роздільники послідовними.
JYelton

2
/(?:[A-Fa-f0-9]{2}[:-]){5}(?:[A-Fa-f0-9]{2})/

Чи схоже це на відповідь прокладок, лише без: xdigit?
Xaisoft


2
/^(([a-fA-F0-9]{2}-){5}[a-fA-F0-9]{2}|([a-fA-F0-9]{2}:){5}[a-fA-F0-9]{2}|([0-9A-Fa-f]{4}\.){2}[0-9A-Fa-f]{4})?$/

Згенерований вираз підтверджує всі типи адрес mac нижче:

01-23-45-67-89-ab
01:23:45:67:89:ab
0123.4567.89ab

Я думаю, що це єдиний, який є повним і правильним.
Вінсент


1

Я не думаю, що основний RegEx є правильним, оскільки він також класифікує

'3D-F2-C9:A6-B3:4F' 

як дійсна MAC-адреса, навіть невірна. Правильним було б:

((([a-zA-z0-9]{2}[-:]){5}([a-zA-z0-9]{2}))|(([a-zA-z0-9]{2}:){5}([a-zA-z0-9]{2})))

Так що кожного разу ви можете вибрати ":" або "-" для всієї MAC-адреси.


0

Ви можете використовувати наступну процедуру, передавши mac-адресу для перевірки,

private static final String MAC_PATTERN = "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$";

private boolean validateMAC(final String mac){          
    Pattern pattern = Pattern.compile(MAC_PATTERN);
    Matcher matcher = pattern.matcher(mac);
    return matcher.matches();             
}


0

Якщо вам потрібні пробіли між номерами, як цей варіант

3D : F2 : C9 : A6 : B3 : 4F

Регекс змінюється на

"^([0-9A-Fa-f]{2}\\s[:-]\\s){5}([0-9A-Fa-f]{2})$"

0

відповідати як 48-розрядному MAC-адресу EUI-48, так і 64-бітній EUI-64:

/\A\h{2}([:\-]?\h{2}){5}\z|\A\h{2}([:\-]?\h{2}){7}\z/

де \ h - символ у [0-9a-fA-F]

або:

/\A[0-9a-fA-F]{2}([:\-]?[0-9a-fA-F]{2}){5}\z|\A[0-9a-fA-F]{2}([:\-]?[0-9a-fA-F]{2}){7}\z/

це дозволяє використовувати "-" або ":" або не використовувати роздільник


0

Можливо найкоротший:

/([\da-f]{2}[:-]){5}[\da-f]{2}/i

Оновлення : Існує кращий спосіб перевірити MAC-адреси в PHP, який підтримує як MAC-адреси в стилі дефісів, так і двократкою. Використовуйте filter_var () :

// Returns $macAddress, if it's a valid MAC address
filter_var($macAddress, FILTER_VALIDATE_MAC);

Як я знаю, він підтримує MAC-адреси в цих формах (x: шістнадцяткове число):

xx:xx:xx:xx:xx:xx
xx-xx-xx-xx-xx-xx
xxxx.xxxx.xxxx

0

Дякую @Moshe за чудову відповідь вище. Провівши ще кілька досліджень, я хотів би додати свої додаткові висновки, як щодо IEEE 802, так і для застосування послідовного використання сепаратора в регулярному вираженні.

Стандартний формат (IEEE 802) для друку MAC-48 адрес у зручній для людини формі становить шість груп з двох шістнадцяткових цифр, розділених дефісами - . Однак широко прийнята конвенція також дозволяє двокрапку: і три групи з чотирьох шістнадцяткових цифр, розділених періодами. .

Повна заслуга @Moshe тут за його первісну заяву, а також @pilcrow за вказівку на те, що IEEE 802 покриває лише гіпси.

Ось регулярний вираз, який застосовує той самий роздільник, який використовується на всій mac-адресі:

^(?:(?:[0-9A-Fa-f]{2}(?=([-:]))(?:\1[0-9A-Fa-f]{2}){5}))$

Демонстрація Regex101

Ось додатковий, що дозволяє взагалі використовувати не роздільник:

^(?:(?:[0-9A-Fa-f]{2}(?=([-:]|))(?:\1[0-9A-Fa-f]{2}){5}))$

Демонстрація Regex101


0

Оскільки MAC-адреса може бути 6 або 20 байтів (infiniband, ...) правильна відповідь:

^([0-9A-Fa-f]{2}:){5}(([0-9A-Fa-f]{2}:){14})?([0-9A-Fa-f]{2})$

ви можете замінити: на [: -.]? якщо ви хочете різних роздільників або їх немає.


-1

Цей невеликий:

(([0-9A-F]{2}[:-]?){6})

Майте на увазі, що дивна суміш декількох символів чи роздільників може пройти.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.