Si può certamente trovare candidati correttamente formattati con una regex .
Dai un'occhiata alla definizione di C Format Specification. (. Utilizzando Microsofts, ma utilizzare ciò che si vuole)
E ':
%[flags] [width] [.precision] [{h | l | ll | w | I | I32 | I64}] type
hai anche il caso particolare della %%
che diventa %
in printf.
È possibile tradurre quel modello in un'espressione regolare:
( # start of capture group 1
% # literal "%"
(?: # first option
(?:[-+0 #]{0,5}) # optional flags
(?:\d+|\*)? # width
(?:\.(?:\d+|\*))? # precision
(?:h|l|ll|w|I|I32|I64)? # size
[cCdiouxXeEfgGaAnpsSZ] # type
) | # OR
%%) # literal "%%"
Demo
e poi in una regex di Python:
import re
lines='''\
Worker name is %s and id is %d
That is %i%%
%c
Decimal: %d Justified: %.6d
%10c%5hc%5C%5lc
The temp is %.*f
%ss%lii
%*.*s | %.3d | %lC | %s%%%02d'''
cfmt='''\
( # start of capture group 1
% # literal "%"
(?: # first option
(?:[-+0 #]{0,5}) # optional flags
(?:\d+|\*)? # width
(?:\.(?:\d+|\*))? # precision
(?:h|l|ll|w|I|I32|I64)? # size
[cCdiouxXeEfgGaAnpsSZ] # type
) | # OR
%%) # literal "%%"
'''
for line in lines.splitlines():
print '"{}"\n\t{}\n'.format(line,
tuple((m.start(1), m.group(1)) for m in re.finditer(cfmt, line, flags=re.X)))
Stampe:
"Worker name is %s and id is %d"
((15, '%s'), (28, '%d'))
"That is %i%%"
((8, '%i'), (10, '%%'))
"%c"
((0, '%c'),)
"Decimal: %d Justified: %.6d"
((9, '%d'), (24, '%.6d'))
"%10c%5hc%5C%5lc"
((0, '%10c'), (4, '%5hc'), (8, '%5C'), (11, '%5lc'))
"The temp is %.*f"
((12, '%.*f'),)
"%ss%lii"
((0, '%s'), (3, '%li'))
"%*.*s | %.3d | %lC | %s%%%02d"
((0, '%*.*s'), (8, '%.3d'), (15, '%lC'), (21, '%s'), (23, '%%'), (25, '%02d'))
Tutto quello che voglio fare, è semplicemente per lo cate "% d" e "% s" all'interno della stringa - per conoscere i loro indici se volete, e non per convertirli in una stampa Python – speller
non potete facilmente analizzarli con una semplice regex, dovete gestire char per char . –
Questo è ovviamente possibile, ma non semplice, preferisco evitarlo. È strano che questa logica, che è all'interno di gcc e clang, non sia disponibile in Python, anche nelle librerie di parsing – speller