Unstructuredunstructured 0.27.6 · Python 3.11+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
21 small wins to finish your pathNext lesson

Cleaners, and element.apply

Text that came out of a real document is rarely tidy. The library ships about twenty small functions that each fix one thing, and one method that runs them over an element.

Here is the shop's FAQ, saved out of a web page by somebody in a hurry. The spacing survived the trip and the layout did not.

text
FAQ

Refunds   take   five  working days.

●   Track your order from the email we send.

●   Codes  go live 4 hours after dispatch.

Call the desk on 215-867-5309

Write to support@shop.example or ravi@example.com.

Page 2 of 2
Example
from unstructured.partition.auto import partition

for element in partition("faq.txt"):
    print(f"{element.category:14s} {element.text!r}")

Two things already happened without being asked. The bullet characters are gone, because a partitioner strips the bullet when it decides a line is a ListItem. The runs of spaces are still there, because nothing has been asked to remove them.

One function, one fix

Example
from unstructured.cleaners.core import clean_extra_whitespace

print(repr(clean_extra_whitespace("Refunds   take   five  working days.")))

Every cleaner has that shape: a string in, a string out. clean_extra_whitespace collapses runs of spaces and newlines into single spaces. clean_bullets removes a leading bullet. clean_trailing_punctuation removes a trailing colon or full stop. clean_non_ascii_chars drops anything outside ASCII.

Running one over an element

An element is not a string, so it has a method for this. apply takes any number of cleaners and runs them over the text in order, replacing it.

Example
from unstructured.partition.auto import partition
from unstructured.cleaners.core import clean_extra_whitespace

elements = partition("faq.txt")
for element in elements:
    element.apply(clean_extra_whitespace)
print(repr(elements[1].text))
print(repr(elements[3].text))

The spacing is fixed in both. apply changes the element in place and returns nothing, so there is no new list to keep; the elements you already have are the cleaned ones.

The one with the switches

clean is several of the others behind one call, each turned on by a keyword. They all default to off.

Example
from unstructured.cleaners.core import clean

messy = "  RISK FACTORS ----------  "
print(repr(clean(messy)))
print(repr(clean(messy, extra_whitespace=True, dashes=True, lowercase=True)))

The first call did nothing, because every switch was off and clean with no arguments is a function that strips the ends. The second did three jobs. If a cleaner seems to be doing nothing, that is nearly always why.

replace_unicode_quotes sounds like it would turn curly quotes into straight ones. It does the opposite: it repairs text where curly quotes were decoded as the wrong bytes, and turns those bytes back into curly quotes. Run it on text that already reads correctly and nothing changes.
Try it yourself
  • Apply clean_trailing_punctuation to the FAQ elements and see which ones change.
  • Call element.apply(clean_extra_whitespace) twice and check the second call is harmless.
  • Pass a function that takes two arguments to apply and read the error.

Every expert started right here.