Extract the words which are either numbers followed by all uppercase English letters or vice versa. There may be special characters in the words. The output need to be shown in uppercase English letters_numbers without any special character. Ex. 676ABC, PQ88, 456@RT, UK_457,8@78*U/T Not valid – 456@Rt (t is small case), GHI 45 (GHI and 45 both are separate words not one word), 787UI56 (rule is number followed by uppercase English letters or vice versa which is 787UI. But it is once again followed by a number which makes it invalid. If you take vice versa, then it is UI56 but 787 makes it invalid)
📌 Challenge Details and Links
ExcelBI Power Query Challenge Number: 191
Challenge Difficulty: ⭐️⭐️⭐️⭐️⭐️
📥Download Sample File
📥Link to the solutions on LinkedIn
Solving the challenge of Extract Valid Structured Words with Power Query
Power Query solution 1 for Extract Valid Structured Words, proposed by Zoran Milokanović:
let
Source = Excel.CurrentWorkbook(){[Name = "Input"]}[Content],
A = {"A" .. "Z"},
a = {"a" .. "z"},
N = {"0" .. "9"},
S = Table.TransformRows(
Source,
each Text.Combine(
List.TransformMany(
List.Select(
Text.Split([Text], " "),
(w) =>
let
c = each List.Intersect({_, Text.ToList(w)}) <> {}
in
List.AllTrue({c(A), not c(a), c(N)})
),
(i) =>
let
w = Text.Select(i, A & N),
e = each List.RemoveItems(Text.SplitAny(w, Text.Combine(_)), {""})
in
{{}, {Text.Combine(e(N) & {"_"} & e(A))}}{Number.From(List.Count(e(A) & e(N)) = 2)},
(i, _) => _
),
", "
)
)
in
S
Power Query solution 2 for Extract Valid Structured Words, proposed by Kris Jaganah:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Ans = Table.AddColumn(
Source,
"Answer Expected",
each
let
a = Text.SplitAny([Text], Text.Combine({"a" .. "z", " "})),
B = List.Transform,
c = List.RemoveNulls(
B(
{1 .. 255},
each Character.FromNumber(
if _ > 47 and _ < 58 then null else if _ > 64 and _ < 91 then null else _
)
)
),
d = B(a, each if Text.Select(_, c) <> "" then _ else null),
e = B(
d,
each
let
x = Text.Remove(_, c)
in
if x = "" then null else x
),
f = Text.Combine(
B(
e,
each
let
x = Text.Select(_, {"A" .. "Z"}) & "_" & Text.Select(_, {"0" .. "9"})
in
if Text.Start(x, 1) = "_" then null else x
),
", "
)
in
f
)
in
Ans
Power Query solution 3 for Extract Valid Structured Words, proposed by Aditya Kumar Darak 🇮🇳:
let
Source = Excel.CurrentWorkbook(){[Name = "data"]}[Content],
Digits = {"0" .. "9"},
Alphabets = {"A" .. "Z"},
Return = Table.AddColumn(
Source,
"Answer",
each [
T = Text.Select([Text], {"a" .. "z", " "} & Digits & Alphabets),
S1 = Text.Split(T, " "),
S2 = List.Transform(
S1,
(f) =>
[
s1 = Splitter.SplitTextByCharacterTransition(Alphabets, Digits)(f),
s2 = List.Transform(
s1,
(x) => Splitter.SplitTextByCharacterTransition(Digits, Alphabets)(x)
),
c = List.Combine(s2),
r = List.Sort(c, 1)
][r]
),
F = List.TransformMany(
S2,
(x) => {List.Count(x)},
(x, y) => if y = 2 then x{0} & "_" & x{1} else null
),
R = Text.Combine(F, ", ")
][R]
)
in
Return
Power Query solution 4 for Extract Valid Structured Words, proposed by Alejandro Simón 🇵🇦 🇪🇸:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Sol = Table.AddColumn(
Source,
"Answer",
each
let
a = Text.Split([Text], " "),
b = k(a, each j(l(_), {"A" .. "Z"})),
c = List.Distinct(l(n(m(Source[Text]), {"A" .. "Z", "a" .. "z", " ", "0" .. "9"}))),
d = k(b, each j(l(_), c)),
e = k(d, each not j(l(_), {"a" .. "z"})),
f = i(e, each n(_, c)),
g = i(
f,
each m(
i(
h({"A" .. "Z"}, {"0" .. "9"})(_),
(x) => m(List.Reverse(List.Sort(h({"0" .. "9"}, {"A" .. "Z"})(x))), "_")
),
"_"
)
),
h = Splitter.SplitTextByCharacterTransition,
i = List.Transform,
j = List.ContainsAny,
k = List.Select,
l = Text.ToList,
m = Text.Combine,
n = Text.Remove
in
m(g, ", ")
)
in
Sol
Power Query solution 5 for Extract Valid Structured Words, proposed by Luan Rodrigues:
let
Fonte = Tabela1,
res = Table.TransformColumns(
Fonte,
{
"Text",
each
let
a = List.Select(
Text.Split(_, " "),
(y) =>
Text.Length(Text.Select(y, {"A" .. "Z"}))
> 0 and Text.Length(Text.Select(y, {"0" .. "9"}))
> 0 and Text.Length(Text.Select(y, {" " .. "/", "[" .. "_"}))
> 0 and Text.Length(Text.Select(y, {"a" .. "z"})) = 0
),
b = Text.Combine(
List.Transform(
a,
each Text.Select(_, {"A" .. "Z"}) & "_" & Text.Select(_, {"0" .. "9"})
),
", "
)
in
b
}
)
in
res
Power Query solution 6 for Extract Valid Structured Words, proposed by 🇮🇷 Navid Esmaeilzadeh اسماعیل زاده:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
A = Table.AddColumn(
Source,
"T1",
each Text.Select([Text], {"0" .. "9", "a" .. "z", "A" .. "Z", " "})
),
B = Table.ExpandListColumn(
Table.TransformColumns(
A,
{
{
"T1",
Splitter.SplitTextByDelimiter(" ", QuoteStyle.Csv),
let
itemType = (type nullable text) meta [Serialized.Text = true]
in
type {itemType}
}
}
),
"T1"
),
C = Table.TransformColumnTypes(B, {{"T1", type text}}),
D = Table.AddColumn(
C,
"Te",
each
if Text.Length(Text.Remove([T1], {"0" .. "9"})) = Text.Length([T1]) then
null
else if Text.Length(Text.Remove([T1], {"0" .. "9"})) = 0 then
null
else if Text.Remove([T1], {"0" .. "9"})
& Text.Remove([T1], {"A" .. "Z"}) = [T1] or Text.Remove([T1], {"A" .. "Z"})
& Text.Remove([T1], {"0" .. "9"}) = [T1]
then
Text.Remove([T1], {"0" .. "9"}) & "_" & Text.Remove([T1], {"A" .. "Z"})
else
null
),
E = Table.SelectRows(D, each ([Te] <> null)),
F = Table.Group(E, {"Text"}, {{"A", each Text.Combine([Te], ","), type text}}),
G = Table.NestedJoin(Source, {"Text"}, F, {"Text"}, "N"),
H = Table.ExpandTableColumn(G, "N", {"A"}, {"N.A"}),
Sol = Table.SelectColumns(H, {"N.A"})
in
Sol
Power Query solution 7 for Extract Valid Structured Words, proposed by Yaroslav Drohomyretskyi:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Words = Table.SelectRows(
Table.AddColumn(
Table.ExpandListColumn(
Table.AddColumn(Source, "Words", each Text.Split([Text], " ")),
"Words"
),
"Format",
each
if [Words]
= Text.Upper([Words]) and Text.Select([Words], {"0" .. "9"})
<> "" and Text.Select([Words], {"A" .. "Z"})
<> ""
then
Text.Select([Words], {"A" .. "Z"}) & "_" & Text.Select([Words], {"0" .. "9"})
else
null
),
each ([Format] <> null)
),
CheckTransitions = Table.AddColumn(
Words,
"CheckTransitions",
each
if List.Count(
Splitter.SplitTextByCharacterTransition({"0" .. "9"}, {"A" .. "Z"})(
Text.Select([Words], {"A" .. "Z", "0" .. "9"})
)
)
< 3
and List.Count(
Splitter.SplitTextByCharacterTransition({"A" .. "Z"}, {"0" .. "9"})(
Text.Select([Words], {"A" .. "Z", "0" .. "9"})
)
)
< 3
then
[Format]
else
null
),
Group = Table.Group(
CheckTransitions,
{"Text"},
{{"Answer", each Text.Combine(_[CheckTransitions], ", ")}}
)
in
Group
Power Query solution 8 for Extract Valid Structured Words, proposed by Ahmed Ariem:
let
source= Excel.CurrentWorkbook(){[Name="tbl"]}[Content],
PromoteHeader = Table.PromoteHeaders(source, [PromoteAllScalars=true]),
AddColumn= Table.AddColumn(PromoteHeader, "spl", each [
f1 = List.Buffer(List.Transform({65..90},Character.FromNumber)),
f2 = List.Buffer(List.Transform({97..122},Character.FromNumber)),
f3 =List.Buffer({ "0".."9"}),
f4 =List.Buffer(List.Transform({33..47}&{58..64}&{91..96}&{123..126},Character.FromNumber)),
txt1= List.Select (List.Transform( Text.Split([Text]," "), (x)=>if Text.Select(x,f1)<>"" and Text.Select(x,f3) <>"" and Text.Select(x,f2) =""then x else null),(x)=>x<> null) ,
txt2 = List.Transform(txt1,(x)=> Text.Remove(x,f4)),
txt3 = List.Transform(txt2,(x)=>
if Text.Select(Text.Trim(x,f3),f3)="" then x else null
),
txt4 = List.Transform(txt3, (x)=> Text.Select(x,f1)&"_"&Text.Select(x,f3)),
txt5 = Text.Combine(txt4,", ")
]
[txt5])
in
Power Query solution 9 for Extract Valid Structured Words, proposed by Challa Sai Kumar Reddy:
let
Source = Excel.CurrentWorkbook(){[Name = "Table1"]}[Content],
Answer = Table.AddColumn(
Source,
"Answer",
each
let
a = Text.Split([Text], " "),
b = List.Select(a, each List.Contains({"A" .. "Z"}, Text.Start(_, 1))),
c = List.Distinct(List.Combine(List.Transform(Source[Text], each Text.ToList(_)))),
d = List.Select(b, each List.Contains(c, Text.Start(_, 1))),
e = List.Select(d, each not List.Contains({"a" .. "z"}, Text.Start(_, 1))),
f = List.Transform(e, each Text.Remove(_, c)),
g = List.Transform(f, each Text.Combine(List.Sort(List.Reverse(Text.ToList(_))), "")),
h = Text.Splitter.SplitTextByCharacterTransition,
i = List.Transform,
j = List.ContainsAny,
k = List.Select,
l = Text.ToList,
m = Text.Combine,
n = Text.Remove
in
m(g, ", ")
)
in
Answer
Solving the challenge of Extract Valid Structured Words with Excel
Excel solution 1 for Extract Valid Structured Words, proposed by Bo Rydobon 🇹🇭:
=MAP(
A2:A11,
LAMBDA(
a,
TEXTJOIN(
", ",
,
MAP(
TEXTSPLIT(
IFNA(
REGEXREPLACE(
a,
"[^w ]|_",
),
a
),
" "
),
LAMBDA(
b,
LET(
c,
IFNA(
REGEXEXTRACT(
b,
"[A-Z]+"
)&"_"®EXEXTRACT(
b,
"d+"
),
),
REPT(
c,
LEN(
c
)-1=LEN(
b
)
)
)
)
)
)
)
)
Excel solution 2 for Extract Valid Structured Words, proposed by Bo Rydobon 🇹🇭:
=MAP(
A2:A11,
LAMBDA(
a,
TEXTJOIN(
", ",
,
MAP(
TEXTSPLIT(
a,
" "
),
LAMBDA(
b,
LET(
m,
MID(
b,
SEQUENCE(
LEN(
b
)
),
1
),
c,
m>"9",
n,
1-ISERR(
-m
),
REPT(
CONCAT(
REPT(
m,
c
),
"_",
REPT(
m,
n
)
),
EXACT(
b,
UPPER(
b
)
)*OR(
m<"0"
)*OR(
c
)*OR(
n
)
)
)
)
)
)
)
)
Excel solution 3 for Extract Valid Structured Words, proposed by Bo Rydobon 🇹🇭:
=MAP(
A2:A11,
LAMBDA(
a,
TEXTJOIN(
", ",
,
IFNA(
MAP(
REGEXEXTRACT(
a,
"b[^a-zs]+b",
1
),
LAMBDA(
b,
REPT(
CONCAT(
REGEXEXTRACT(
b,
"[A-Z]",
1
),
"_",
REGEXEXTRACT(
b,
"d",
1
)
),
REGEXTEST(
b,
"[^w]|_"
)
)
)
),
""
)
)
)
)
Excel solution 4 for Extract Valid Structured Words, proposed by محمد حلمي:
=MAP(
A2:A11,
LAMBDA(
a,
TEXTJOIN(
", ",
,
MAP(
TEXTSPLIT(
a,
" "
),
LAMBDA(
a,
LET(
i,
MID(
a,
SEQUENCE(
LEN(
a
)
),
1
),
j,
ISNUMBER(
-i
),
REPT(
CONCAT(
REPT(
i,
i>"9"
),
"_",
&REPT(
i,
j
)
),
EXACT(
a,
UPPER(
a
)
)* OR(
i<"0"
)*OR(
j
)
)
)
)
)
)
)
)
Excel solution 5 for Extract Valid Structured Words, proposed by Julian Poeltl:
=MAP(
A2:A11,
LAMBDA(
T,
LET(
SP,
TEXTSPLIT(
T,
{" ",
", "}
),
TEXTJOIN(
", ",
,
IFERROR(
MAP(
SP,
LAMBDA(
A,
LET(
SP,
MID(
A,
SEQUENCE(
LEN(
A
)
),
1
),
C,
ISNUMBER(
MAP(
SP,
LAMBDA(
A,
XMATCH(
TRUE,
EXACT(
A,
CHAR(
64+SEQUENCE(
26
)
)
),
0
)
)
)
),
NL,
ISNUMBER(
MAP(
SP,
LAMBDA(
A,
XMATCH(
TRUE,
EXACT(
A,
CHAR(
97+SEQUENCE(
26
)
)
),
0
)
)
)
),
N,
ISNUMBER(
SP*1
),
O,
MAP(
C,
N,
LAMBDA(
A,
B,
OR(
A,
B
)
)
),
F,
FILTER(
C,
O
),
IF(
AND(
SUM(
--DROP(
F<>DROP(
F,
1
),
-1
)
)=1,
SUM(
--C
),
SUM(
--N
),
SUM(
--NL
)=0
),
TEXTJOIN(
"_",
,
CONCAT(
FILTER(
SP,
C
)
),
CONCAT(
FILTER(
SP,
N
)
)
),
""
)
)
)
),
""
)
)
)
)
)
Excel solution 6 for Extract Valid Structured Words, proposed by JvdV -:
=IFNA(
REGEXREPLACE(
REGEXREPLACE(
A2:A11,
"[^A-Za-zd ]+",
),
"b((d+)([A-Z]+)|((?3))(d+))b(?=(.+(?1)))?|.",
"${3:+$3_}${4:+$4_}$2$5${6:+, }"
),
""
)
Perfect usecase for replacement string conditionals. If you haven't allready read about them on my blog:
https://buymeacoffee.com/jvdv/regexreplace-replacement-string-conditionals
For those interested; In the inner REGEXREPLACE()
Solving the challenge of Extract Valid Structured Words with Python in Excel
Python in Excel solution 1 for Extract Valid Structured Words, proposed by Abdallah Ally:
import pandas as pd
import re
def extract_words(text):
pattern1 = r'[^ A-Za-z0-9]'
pattern2 = r'b(d+)([A-Z]+)b|b([A-Z]+)(d+)b'
matches = re.findall(pattern2, re.sub(pattern1, '', text))
joined_matches = [('_'.join(x[:2][::-1]), '_'.join(x[2:])) for x in matches]
final_text = ', '.join([x for y in joined_matches for x in y if x != '_'])
return final_text
file_path = 'PQ_Challenge_191.xlsx'
df = pd.read_excel(file_path)
# Perform data wrangling
df = df.replace(float('nan'), '')
df['My Answer'] = df['Text'].map(extract_words)
df['Check'] = df['Answer Expected'] == df['My Answer']
df
&&
