Write a Python function that determines whether text in a string is quoted
New here? Learn about Bountify and follow @bountify to get notified of new bounties! x

The goal here is to write a Python function that, given a string and a position in that string, can determine whether the text at that position is inside of a quotation. This is complicated by a few factors: (1) it needs to be able to handle both straight and curly quotes, (2) it needs to handle the weird case of multi-paragraph quotations, where the first n-1 paragraphs have only open quotation marks and the final paragraph has both opening and closing quotes, (3) the quotation marks can be used outside the context of a quote (e.g., in the sentence The dog's bark was loud or He was 6' tall or There's something funny smelling in John's sisters' apartment., and (4) they can be nested, as in John's sister said, "The funny smell might be John's 'friend' Jake.", where the whole thing should count as being in quotes. The quotation marks themselves can be treated however you'd like.

Here are some test cases:

This sentence has a "quotation", if you can even call it that.

FFFFFFFFFFFFFFFFFFFFFTTTTTTTTTFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

(It doesn't need to return the whole string, since it takes as input a position. This is just for illustration.)

The 1950's were a very fun time...for nobody except the Jones' dog.

FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF

John said, "He told me that yesterday.
"But now I've forgotten.
"I asked him to tell me again."

FFFFFFFFFFFFTTTTTTTTTTTTTTTTTTTTTTTTTT
TTTTTTTTTTTTTTTTTTTTTTTT
TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTF
awarded to alexanderk23

Crowdsource coding tasks.

2 Solutions


string = """
John said, "He told me that yesterday.
"But now I\'ve forgotten.
"I asked him to tell me again."
"""

def findQuotePositions(string):
    list = []

    beginCompare = '"'
    endCompare = '"'

    if "“" in string:
        beginCompare = "“"
        endCompare = "”"

    x = 0
    y = 0
    xFound = False
    yFound = False

    for i, c in enumerate(string):
        if c == beginCompare:
            if not xFound:
                xFound = True
                x = i
            else:
                if not yFound:
                    if c == endCompare:
                        pC = string[i-1]
                        if pC != '\n':
                            yFound = True
                            y = i
        if xFound and yFound:
            pair = (x, y)
            list.append(pair)
            xFound = False
            yFound = False

    return list

def inQuote(string, index):
    positions = findQuotePositions(string)
    for p in positions:
        x = p[0]
        y = p[1]
        if index > x and index < y:
            return True
    return False

a = inQuote(string, 13)
print a

I didn't know if mixed quotes are possible (curly and normal). I have written a function that supports " and ” as a quotation start.

You can also check the solution live here: http://repl.it/cRT/2

Note that if a lot of calls are being made, it is better to calculate positions separately (and not in each inQuote function call) and pass them to the function, the following example does that: http://repl.it/cRU

View Timeline