Почему вторая локализованная строка не отображается правильно в консоли в этом примере?
Найдено 3 слова IPv6 2001: 0db8: 0000: 0000: 0000: FF00: 0042: 8329 2001: 0db8 :: --- неправильный вывод здесь :: 1
#включают <iostream> #включают <итератор> #включают <строка> #включают <регулярное выражение> int main () { std :: string s = "ipv4 модель 127.0.0.1 " "в прямом эфире 2001: 0db8: 0000: 0000: 0000: ff00: 0042: 8329 " "другой 2001: 0db8 :: ff00: 0042: 8329 " "почтовый индекс :: 1 "; std :: regex ex_ipv6 ("(([0-9a-FA-F] {1,4}:) {} 7,7 [0-9a-FA-F] {1,4} | ([0-9a-FA-F] {1 , 4}:) {} 1,7: | ([0-9a-FA-F] {1,4}:) {1,6}: [0-9a-FA-F] {1,4} | ([0-9a-FA-F] {1,4}:) {1,5} (: [0-9a-FA-F] {1,4}) {1,2} | ([0-9a -fa-F] {1,4}:) {1,4} (: [0-9a-FA-F] {1,4}) {1,3} | ([0-9a-FA-F] {1,4}:) {1,3} (: [0-9a-FA-F] {1,4}) {1,4} | ([0-9a-FA-F] {1,4} :) {1,2} (: [0-9a-FA-F] {1,4}) {1,5} | [0-9a-FA-F] {1,4}: ((: [0 -9а-FA-F] {1,4}) {1,6}) |: ((: [0-9a-FA-F] {1,4}) {1,7} |:) | fe80: (: [0-9a-FA-F] {0,4}) {0,4}% [0-9a-Za-Z] {1} |: :( FFFF (: 0 {1,4}) {0,1}:) {0,1} ((25 [0-5] | (2 [0-4] | 1 {0,1} [0-9]) {0,1} [0-9 ])) {3,3} (25 [0-5] |. (2 [0-4] | 1 {0,1} [0-9]) {0,1} [0-9]) | ( [0-9a-FA-F] {1,4}:) {1,4}: ((25 [0-5] | (2 [0-4] | 1 {0,1} [0-9] ) {0,1} [0-9])) {3,3} (25 [0-5] |. (2 [0-4] | 1 {0,1} [0-9]) {0, 1} [0-9]))"); auto words_ipv6_begin = std :: sregex_iterator (s.begin (), s.end (), ex_ipv6); auto words_ipv6_end = std :: sregex_iterator (); if (std :: regex_search (s, ex_ipv6)) { станд :: соиЬ << "Найденный " << std :: distance (words_ipv6_begin, words_ipv6_end) << " слова IPv6 \ n"; for (; words_ipv6_begin! = words_ipv6_end; words_ipv6_begin ++) { станд :: соиЬ << (* Words_ipv6_begin) .str () << "\ п"; } } }
Ваша проверка префикса принимает строку намного раньше, чем должна. Экспресс группа ([0-9a-fA-F]{1,4}:){1,7}:
помечает адрес до перехода как действительный, использует строку и проверяет ::ff00:0042:8329
не соответствует ни одному оставшемуся образцу (и также считается отдельным адресом, если это так).
Пара замечаний о вашем использовании регулярных выражений. {7,7}
может быть просто написано как {7}
, IPv6-адреса должны быть [0-9a-f]
когда представлен как base16, так что вы можете отказаться от [A-F]
чеки.
#include <algorithm>
#include <iostream>
#include <regex>
#include <string>
// RFC5952 outlines canonical formatting for rendering IPv6 addresses as
// text. Hex values in an address SHOULD be lowercase. Addresses can be
// shortened ONCE using the symbol '::'. Whitespace is actually processed
// as part of the pattern, so use \\s to match whitespace.
int main() {
std::string ipv6 =
"(?:"// For the first 6 fields, match addresses with no jump (::)...
" (?: (?:[0-9a-f]{1,4}:){6}"// ...or a jump.
" | :: (?:[0-9a-f]{1,4}:){5}"" | (?: [0-9a-f]{1,4})? :: (?:[0-9a-f]{1,4}:){4}"" | (?: (?:[0-9a-f]{1,4}:){0,1} [0-9a-f]{1,4})? :: (?:[0-9a-f]{1,4}:){3}"" | (?: (?:[0-9a-f]{1,4}:){0,2} [0-9a-f]{1,4})? :: (?:[0-9a-f]{1,4}:){2}"" | (?: (?:[0-9a-f]{1,4}:){0,3} [0-9a-f]{1,4})? :: (?:[0-9a-f]{1,4}:) "" | (?: (?:[0-9a-f]{1,4}:){0,4} [0-9a-f]{1,4})? :: "" ) "// Match the base10/16 addresses with no jump (suffix of above).
" (?: [0-9a-f]{1,4} : [0-9a-f]{1,4} "" | (?: (?: 25[0-5] | 2[0-4][0-9] | [01]?[0-9]?[0-9])\\.){3} "" (?: (?: 25[0-5] | 2[0-4][0-9] | [01]?[0-9]?[0-9])) "" ) "// Not any above. Check to see if jump is between last 2 fields of addr.
" | (?: (?:[0-9a-f]{1,4}:){0,5} [0-9a-f]{1,4})? :: [0-9a-f]{1,4} "" | (?: (?:[0-9a-f]{1,4}:){0,6} [0-9a-f]{1,4})? :: "")";
// End of ipv6 string pattern.
// Convert readable pattern above into the applicable regex pattern.
ipv6.erase(std::remove_if(ipv6.begin(), ipv6.end(), ::isspace), ipv6.cend());
std::regex ipv6_pattern(ipv6);
const std::string test = "ipv4 model 127.0.0.1 ""live 2001:0db8:0000:0000:0000:ff00:0042:8329 ""another 2001:0db8::ff00:0042:8329 ""zip form ::1 ";
auto result = std::sregex_iterator(test.cbegin(), test.cend(), ipv6_pattern);
const auto results_end = std::sregex_iterator();
if (result != results_end) {
std::cout << "Found "<< std::distance(result, results_end)
<< " IPv6 address matches.\n";
while (result != results_end) {
std::cout << (*result++).str() << '\n';
}
}
}
Приставка:
Found 3 IPv6 address matches.
2001:0db8:0000:0000:0000:ff00:0042:8329
2001:0db8::ff00:0042:8329
::1