How say regex to ignore delimiter which I need delete

Viewed 96

I learned how to work with strings and I have a string like:

"one; two\t; "three;2"; four;\t\t" 

and if this string has "" then I need to ignore delimiter in this ""

I want to get:

one two three;2 four

How can I do this?

1 Answers

Update I've merged the two expressions approach into the following RegEx that should work in different RegEx compilers that support lookarounds that contian expressions of arbitrary length.

Here is the expression:

(?:(?<=\")[^\"]+(?=\"[\t]*;)|\w+)+

Testing with the input below:

s='"zero,;6"\t\t; one; two\t\t; "three,;2"; four;\t\t; "five;six"\t; "seven";'

then running in python (re module's import is not shown):

re.findall(r'(?:(?<=\")[^\"]+(?=\"[\t]*;)|\w+)+', s)

(Note: you could also specify [\t\v\r\n\f]* instead of [\t]* if your file is expected to contain these additional special characters.)

yields the following list:

['zero,;6', 'one', 'two', 'three,;2', 'four', 'five;six', 'seven']

Original One way to ignore the delimiter's occurrence inside a double-quoted substring would be by employing lookarounds.

For example to match a double-quoted substring without also including the quotes in the resulting matched substring, a combination of positive lookahead and lookbehind can be used in the following way:

(?<=\")([^\"]+)(?=\";)

The (?<=\") is an assertion for the existence of a preceding double-quote, whereas the (?=\";) is an assertion for the existence of a trailing double quote or a semicolon delimiter. The capturing group ([^\"]+) matches any sequence of characters, except a double-quote to avoid double registration of quotes, inside these quotes. If the above assertions hold then we have a matching substring.

For a normal element, we could match a sequence containing only alphanumeric characters, like this:

\w+

Now combining these two through the use of a non-capturing group we have:

(?:(?<=\")([^\"]+)(?=\";)|(\w+))+

Note: A mandatory step for this approach is to first discard any tab character occurrence. If you are in Python this can be done using the str's method replace or using the re module's sub like this:

re.sub(r'[\t\v\r\n\f]', r'', string)

(I also include other special characters, but you can omit them if it is safe for your use case)

Then, you can use either search or findall from the re module, giving the RegEx above.

If you opt for findall then you should use the above expression without any group capturing:

re.findall(r'(?:(?<=\")[^\"]+(?=\";)|\w+)+', string)

Example

For the following input string:

string = '"ty,;6"\t\t; one; two\t\t; "three,;2";  four;\t\t; "fdf;fdfgf"\t; "fdfdf";'

Running the substitution step the result is:

> str_clean = re.sub(r'[\t\v\r\n\f]', r'', string)
 '"ty,;6"; one; two; "three,;2";  four;; "fdf;fdfgf"; "fdfdf";'

Then, running the final RegEx:

> re.findall(r'(?:(?<=\")[^\"]+(?=\";)|\w+)+', str_clean)
 ['ty,;6', 'one', 'two', 'three,;2', 'four', 'fdf;fdfgf', 'fdfdf']
Related