/*
========================================================
Title: Extract Whole Numbers Not Adjacent to Letters
========================================================
Definition:
A whole number is a maximal sequence of digits that is
NOT directly adjacent to an alphabetic character.
Examples:
<8408<f16f15>9387541<47g28<829oiew0>>2i7>3<y5>8cas>616>9>
Output:
8408
9387541
3
616
9
Why this approach?
* Fast (single pass)
* No regex overhead
* Easy to understand
* Production-friendly
*/
#include <cctype>
#include <iostream>
#include <string>
int main()
{
const std::string text =
"<8408<f16f15>9387541<47g28<829oiew0>>2i7>3<y5>8cas>616>9>";
std::size_t i = 0;
while (i < text.size())
{
if (!std::isdigit(static_cast<unsigned char>(text[i]))) {
++i;
continue;
}
const std::size_t start = i;
while (i < text.size() &&
std::isdigit(static_cast<unsigned char>(text[i])))
{
++i;
}
const std::size_t end = i;
const bool left_is_letter =
start > 0 &&
std::isalpha(
static_cast<unsigned char>(text[start - 1]));
const bool right_is_letter =
end < text.size() &&
std::isalpha(
static_cast<unsigned char>(text[end]));
if (!left_is_letter && !right_is_letter) {
std::cout
<< text.substr(start, end - start)
<< '\n';
}
}
}
/*
run:
8408
9387541
3
616
9
*/