I want to extract relevant information from the text column of a DataFrame using regular expressions.
If I have this DataFrame:
+-------------------------------------------+
|text |
+-------------------------------------------+
|Hello this is a test +34666666666 677777777|
|Hello this a test 44442222M 33335555C |
+-------------------------------------------+
I would like to have the following output:
+-------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|text |match |
+-------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Hello this is a test +34666666666 677777777|[(PHONE,u'34666666666',u'677777777')]|
|Hello this a test 44442222M 33335555C |[(DNI, u'44442222M',u'33335555C')] |
+-------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
I've try using this:
pat_list = [['PHONE','\\b((\+?34([ \t|\-])?)?[9|6|7]((\d{1}([ \t|\-])?[0-9]{3})|(\d{2}([ \t|\-])?'
'[0-9]{2}))([ \t|\-])?[0-9]{2}([ \t|\-])?[0-9]{2})\\b'],
['DNI','\\b(\d{8})([A-Z])\\b']]
l1 = ['Hello this is a test +34666666666 677777777','Hello this a test 44442222M 33335555C']
l = zip(l1)
df = spark.createDataFrame(l,['text'])
rdd = df.rdd.map(list)
def parse_pat(row, col_number, patterns):
column = row[col_number]
hit_words = []
for patron in patterns:
patron_comp = re.compile(patron[1], re.IGNORECASE)
match = patron_comp.search(column)
if match:
hit_words.append(patron[0])
find= re.findall(patron[1], column, re.DOTALL)
hit_words.append(' '.join(str(x) for x in find))
myrow = list(row)
myrow.append(hit_words)
return myrow
rdd_parse_pat = rdd.map(lambda row: (parse_pat(row, col_number=0, patterns=pat_list)))
df_out = rdd_parse_pat.toDF(['text','match'])
But I get this:
df_out.show(truncate=False)
+-------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|text |match |
+-------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
|Hello this is a test +34666666666 677777777|[PHONE, (u'34666666666', u'34', u'', u'6666', u'6666', u'', u'', u'', u'', u'') (u'677777777', u'', u'', u'7777', u'7777', u'', u'', u'', u'', u'')]|
|Hello this a test 44442222M 33335555C |[DNI, (u'44442222', u'M') (u'33335555', u'C')] |
+-------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------+
Does anyone know how could I do it?
[ \t|\-]and[9|6|7]? Because I don't think you're doing what you think you're doing. Also,{1}is redundant.\b,\+?can't match because+is a non word character use(?<=\W)instead, seems you need non capturing groups(?:..)instead of groups(..)