Add initcap prototype / tests

This commit is contained in:
Dmitry Kardymon 2023-06-30 13:11:06 +00:00
parent 3b7f6a4324
commit 1cf021c0b1
5 changed files with 98 additions and 0 deletions

View File

@ -1253,3 +1253,7 @@ Result:
│ A240 │ │ A240 │
└──────────────────┘ └──────────────────┘
``` ```
## initcap
Convert the first letter of each word to upper case and the rest to lower case. Words are sequences of alphanumeric characters separated by non-alphanumeric characters.

View File

@ -1113,3 +1113,7 @@ A text with tags .
The content within <b>CDATA</b> The content within <b>CDATA</b>
Do Nothing for 2 Minutes 2:00 &nbsp; Do Nothing for 2 Minutes 2:00 &nbsp;
``` ```
## initcap {#initcap}
Переводит первую букву каждого слова в строке в верхний регистр, а остальные — в нижний. Словами считаются последовательности алфавитно-цифровых символов, разделённые любыми другими символами.

78
src/Functions/initcap.cpp Normal file
View File

@ -0,0 +1,78 @@
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionStringToString.h>
namespace DB
{
namespace
{
struct InitcapImpl
{
static void vector(const ColumnString::Chars & data,
const ColumnString::Offsets & offsets,
ColumnString::Chars & res_data,
ColumnString::Offsets & res_offsets)
{
res_data.resize(data.size());
res_offsets.assign(offsets);
array(data.data(), data.data() + data.size(), res_data.data());
}
static void vectorFixed(const ColumnString::Chars & data, size_t /*n*/, ColumnString::Chars & res_data)
{
res_data.resize(data.size());
array(data.data(), data.data() + data.size(), res_data.data());
}
private:
static void array(const UInt8 * src, const UInt8 * src_end, UInt8 * dst)
{
const auto flip_case_mask = 'A' ^ 'a';
auto is_lower_alpha = [](UInt8 c) { return c >= 'a' && c <= 'z'; };
auto is_upper_alpha = [](UInt8 c) { return c >= 'A' && c <= 'Z'; };
//auto is_digit = [](UInt8 c) { return c >= '0' && c <= '9'; };
bool prev_is_alpha = false;
for (; src < src_end; ++src, ++dst)
{
bool lower = is_lower_alpha(*src);
bool is_alpha = lower || is_upper_alpha(*src);
if (!is_alpha)
{
*dst = *src;
}
else if (!prev_is_alpha)
{
if (lower)
*dst = *src ^ flip_case_mask;
else
*dst = *src;
}
else
{
if (!lower)
*dst = *src ^ flip_case_mask;
else
*dst = *src;
}
prev_is_alpha = is_alpha;
}
}
};
struct NameInitcap
{
static constexpr auto name = "initcap";
};
using FunctionInitcap = FunctionStringToString<InitcapImpl, NameInitcap>;
}
REGISTER_FUNCTION(Initcap)
{
factory.registerFunction<FunctionInitcap>({}, FunctionFactory::CaseInsensitive);
}
}

View File

@ -0,0 +1,6 @@
Hello
Hello
Hello World
Yeah, Well, I`M Gonna Go Build My Own Theme Park
Crc32ieee Is Best Function

View File

@ -0,0 +1,6 @@
select initcap('');
select initcap('Hello');
select initcap('hello');
select initcap('hello world');
select initcap('yeah, well, i`m gonna go build my own theme park');
select initcap('CRC32IEEE is best function');