Pep Skipepep
Pep Skipepep

Reputation: 49

Get the substring from the string by second vowels from behind the words

I want to do this:

a = "Describe"

I want to split "Describe" by the second vowel words from behind so it will be "Descri" and "be".

Another example is "Public" which should split into "Pu" and "blic".

I tried:

vowel = "AaIiUuEeOo"
consonant = "BbCcDdFfGgHhJjKkLlMmNnPpQqRrSsTtVvWwXxYyZz"
p = []
for char in words[::-1]:
    if char in consonant:
        p.append(char)
    elif char in vokal:
        p.append(char)
        break

How can I achieve this?

Upvotes: 2

Views: 830

Answers (5)

Ajax1234
Ajax1234

Reputation: 71471

You can use string slicing:

def s_split(s):
   l = [i for i in range(len(s)) if s[i].lower() in 'aeiou']
   return [s[:l[len(l) > 2]+1], s[l[len(l) > 2]+1:]]

Output:

['Pu', 'blic']
['Descri', 'be']
['i', 'e']
['i', 'bbe']
['Descri', 'be']

Upvotes: 1

Jan
Jan

Reputation: 43199

Just to put my two cents in, you could use an iterator function:

strings = ["Public", "Describe", "ie", "ababbaba"]

def split_by_vowel(string):

    # variables
    vowels, cnt, buffer = ["aeiouAEIOU", 0, ""]
    it = iter(string)
    parts = list()

    while True:
        try:
            char = next(it)
            buffer += char
            if char in vowels:
                cnt += 1
                parts.append(buffer)
                buffer = ""
        except StopIteration:
            if buffer:
                parts.append(buffer)
            break

    return ["".join(part for part in parts[0:cnt-1]), "".join(parts[cnt-1:])]


for string in strings:
    print(split_by_vowel(string))

This yields

['Pu', 'blic']
['Descri', 'be']
['i', 'e']
['ababba', 'ba']

Upvotes: 0

RoadRunner
RoadRunner

Reputation: 26335

Here's another solution. It first iterates the word in reverse to find the nth last letter that is a vowel, and returns it's index. Then you can simply return a tuple of the word split at the nth vowels index. If no nth vowel is found, None is returned and the full word is just returned.

def get_nth_last_vowel(items, n):
    vowels = {"a", "e", "i", "o", "u"}

    count = 0
    for i in reversed(range(len(items))):

        if items[i].lower() in vowels:
            count += 1

            if count == n:
                return i

def split_nth_last_vowel(word, n):
    idx = get_nth_last_vowel(word, n)

    return word[: idx + 1], word[idx + 1 :] if idx != None else word

Output:

>>> split_nth_last_vowel("Public", 2)
('Pu', 'blic')
>>> split_nth_last_vowel("Describe", 2)
('Descri', 'be')
>>> split_nth_last_vowel("ibe", 2)      
('i', 'be')
>>> split_nth_last_vowel("ie", 2)  
('i', 'e')

Upvotes: 0

ggorlen
ggorlen

Reputation: 57384

You can use the regex ^(.*[AaIiUuEeOo])(?=.*[AaIiUuEeOo])(.+)$. The idea is to capture everything up to a vowel that is followed by another vowel and, optionally some other characters which will be placed in the second capture group.

>>> import re
>>> pattern = r"^(.*[AaIiUuEeOo])(?=.*[AaIiUuEeOo])(.+)$"
>>> re.match(pattern, "Describe").groups()
('Descri', 'be')
>>> re.match(pattern, "Public").groups()
('Pu', 'blic')
>>> re.match(pattern, "ibe").groups()
('i', 'be')
>>> re.match(pattern, "ie").groups()
('i', 'e')

If the string doesn't have at least two vowels, make sure to test for None before calling groups() on the result.

Another idea is to use itertools.groupby which is clunkier but fun and generalizes well to any n or any set of characters (or iterables, for that matter--I stuck to strings here).

from itertools import groupby

def nth_from_rear(s, n=2, matches="aeiou"):
    def nth_counter(n=2, count=0):
        def cb(x):
            nonlocal count

            if x.lower() in matches:
                count += 1

            return count >= n

        return cb

    groups = groupby(s[::-1], key=nth_counter(n))
    return ["".join(x)[::-1] for _, x in groups][::-1]


if __name__ == "__main__":
    tests = [
        ["Public", 2],
        ["Describe", 2],
        ["ie", 2],
        ["ibbe", 2],
        ["Describe", 0],
        ["Describing", 1],
        ["Describe", 3],
        ["ababbaba", 4],
    ]

    for s, n in tests:
        print(s.rjust(10), n, nth_from_rear(s, n))

Output:

    Public 2 ['Pu', 'blic']
  Describe 2 ['Descri', 'be']
        ie 2 ['i', 'e']
      ibbe 2 ['i', 'bbe']
  Describe 0 ['Describe']
Describing 1 ['Describi', 'ng']
  Describe 3 ['De', 'scribe']
  ababbaba 4 ['a', 'babbaba']

Upvotes: 2

Sayandip Dutta
Sayandip Dutta

Reputation: 15872

If you want without using any libraries:

vowel = "AaIiUuEeOo"
consonant = "BbCcDdFfGgHhJjKkLlMmNnPpQqRrSsTtVvWwXxYyZz"
p = []
words = 'Public'
vowelCount = 0
secondPart = ''
firstPart = ''
for index, char in enumerate(words[::-1]):
    if char in vowel:
      vowelCount += 1
      if vowelCount == 2:
        firstPart = words[:-index]
        break
    secondPart += char
secondPart = secondPart[::-1]
print(firstPart, secondPart)

Output:

Pu blic

Upvotes: 0

Related Questions