2
votes

Existe-t-il un moyen efficace de diviser une chaîne entre deux chaînes?

J'essaie de diviser une chaîne pour extraire quelques morceaux de chaîne requis de l'intérieur de cette chaîne. La chaîne que j'ai est la suivante:

def find_between(s, start, end):
    return (s.split(start))[1].split(end)[0]

start = 'conf/'
end = '/'
res=find_between(s,start,end)

Je veux extraire la sous-chaîne après 'conf' entre les deux barres obliques.

icdcs
icde
icde

Ainsi pour les chaînes ci-dessus je veux extraire:

conf/icdcs/ShethL86
conf/icde/BhargavaMRS89
conf/icde/BhargavaNS88

J'ai réussi à écrire le code suivant pour extraire la valeur requise:

s='conf/icdcs/BarbaraGS86|conf/icdcs/ShethL86|conf/icde/BhargavaMRS89|conf/icde/BhargavaNS88|conf/icde/BhargavaR88|conf/icde/ElmagarmidH88|conf/infocom/BadalM84|conf/sigmod/Skeen81|conf/sosp/PresottoM83|conf/vldb/Gray81|journals/cacm/EswarranGLT76|journals/cacm/Lamport78|journals/computer/Alexandridis86|journals/computer/Goguen86|journals/computer/KartashevK86|journals/csur/BernsteinG81|journals/csur/DavidsonG85|journals/csur/Kohler81|journals/jacm/Papadimitriou79b|journals/tc/Avizinis76|journals/tc/Garcia-Molina82|journals/tocs/BirrelN84|journals/tocs/CheritonZ85|journals/tocs/Reed83|journals/tods/Herlihy87|journals/tods/KungR81|journals/tse/BhargavaR89|journals/tse/BlackHJLC87|journals/tse/Randell75|journals/tse/SkeenS83'


2 commentaires

Vous voudrez peut-être consulter le module re .


Avez-vous divisé le texte par «|» avant de faire ça?


4 Réponses :


2
votes

split () est votre ami. si vous savez que vous voulez toujours obtenir ce qui se trouve après conf / , alors divisez d'abord la piqûre.

print(set(confs))
# {'vldb', 'sigmod', 'icdcs', 'sosp', 'icde', 'infocom'}

Ensuite, vous pouvez diviser les chaînes résultantes sur le / suivant et prendre la première partie de chaque élément.

confs = [i.split('/')[0] for i in s.split('conf/') if i.strip()]

print(confs)
# ['icdcs', 'icdcs', 'icde', 'icde', 'icde', 'icde', 'infocom', 'sigmod', 'sosp', 'vldb']

Si vous voulez juste les valeurs uniques, vous pouvez utiliser set () pour supprimer les doublons.

print(s.split('conf/'))
# ['', 'icdcs/BarbaraGS86|',
#  'icdcs/ShethL86|',
#  'icde/BhargavaMRS89|',
#  'icde/BhargavaNS88|',
#  'icde/BhargavaR88|',
#  'icde/ElmagarmidH88|',
#  'infocom/BadalM84|',
#  'sigmod/Skeen81|',
#  'sosp/PresottoM83|',
#  'vldb/Gray81|journals/cacm/EswarranGLT76|journals/cacm/Lamport78|journals/computer/Alexandridis86|journals/computer/Goguen86|journals/computer/KartashevK86|journals/csur/BernsteinG81|journals/csur/DavidsonG85|journals/csur/Kohler81|journals/jacm/Papadimitriou79b|journals/tc/Avizinis76|journals/tc/Garcia-Molina82|journals/tocs/BirrelN84|journals/tocs/CheritonZ85|journals/tocs/Reed83|journals/tods/Herlihy87|journals/tods/KungR81|journals/tse/BhargavaR89|journals/tse/BlackHJLC87|journals/tse/Randell75|journals/tse/SkeenS83']

Je vois un tas des autres les réponses se divisent sur | , ce qui est bien, mais cela crée plus d'éléments dans la liste à parcourir qu'il ne semble nécessaire compte tenu de votre entrée. Le fractionnement sur conf / garantit que chaque élément a quelque chose de valeur. Vous prenez juste la première partie de chacun et vous êtes sur votre chemin.


0 commentaires

0
votes

Utilisation de Regex. re.findall -> Lookbehind & Lookahead

Ex:

['icdcs', 'icdcs', 'icde', 'icde', 'icde', 'icde', 'infocom', 'sigmod', 'sosp', 'vldb']

Sortie :

import re

s='conf/icdcs/BarbaraGS86|conf/icdcs/ShethL86|conf/icde/BhargavaMRS89|conf/icde/BhargavaNS88|conf/icde/BhargavaR88|conf/icde/ElmagarmidH88|conf/infocom/BadalM84|conf/sigmod/Skeen81|conf/sosp/PresottoM83|conf/vldb/Gray81|journals/cacm/EswarranGLT76|journals/cacm/Lamport78|journals/computer/Alexandridis86|journals/computer/Goguen86|journals/computer/KartashevK86|journals/csur/BernsteinG81|journals/csur/DavidsonG85|journals/csur/Kohler81|journals/jacm/Papadimitriou79b|journals/tc/Avizinis76|journals/tc/Garcia-Molina82|journals/tocs/BirrelN84|journals/tocs/CheritonZ85|journals/tocs/Reed83|journals/tods/Herlihy87|journals/tods/KungR81|journals/tse/BhargavaR89|journals/tse/BlackHJLC87|journals/tse/Randell75|journals/tse/SkeenS83'
start = 'conf/'
end = '/'

print(re.findall(r"(?<={}).*?(?={})".format(re.escape(start),re.escape(end)), s)) 


1 commentaires

Une explication du fonctionnement de cette expression régulière, ainsi que re.escape pourraient être utiles car il s'agit d'une implémentation assez compliquée par rapport à d'autres réponses



0
votes

Utilisez simplement split :

prefix = 'conf/'
substrings = [p.split('/')[1] for p in s.split('|') if p.startswith(prefix)]
print(substrings)


0 commentaires

0
votes

Votre réponse n'est extraite qu'une seule fois car vous ne choisissez que le premier résultat de votre split(start):

def find_between(s, start, end):
    for x in s.split('|'):
        if x.startswith(start):
            # yield here will allow you to iterate
            # over the function
            yield x.split(start)[1].split(end)[0]

s='conf/icdcs/BarbaraGS86|conf/icdcs/ShethL86|conf/icde/BhargavaMRS89|conf/icde/BhargavaNS88|conf/icde/BhargavaR88|conf/icde/ElmagarmidH88|conf/infocom/BadalM84|conf/sigmod/Skeen81|conf/sosp/PresottoM83|conf/vldb/Gray81|journals/cacm/EswarranGLT76|journals/cacm/Lamport78|journals/computer/Alexandridis86|journals/computer/Goguen86|journals/computer/KartashevK86|journals/csur/BernsteinG81|journals/csur/DavidsonG85|journals/csur/Kohler81|journals/jacm/Papadimitriou79b|journals/tc/Avizinis76|journals/tc/Garcia-Molina82|journals/tocs/BirrelN84|journals/tocs/CheritonZ85|journals/tocs/Reed83|journals/tods/Herlihy87|journals/tods/KungR81|journals/tse/BhargavaR89|journals/tse/BlackHJLC87|journals/tse/Randell75|journals/tse/SkeenS83'

start = 'conf/'
end = '/'

a = [x for x in find_between(s, start, end)]

# ['icdcs', 'icdcs', 'icde', 'icde', 'icde', 'icde', 'infocom', 'sigmod', 'sosp', 'vldb']

En choisissant simplement split (start ) [1] , vous n'obtenez que `` icdcs / BarbaraGS86 | '. Donc, vous savez que votre logique finale est solide, vous voulez juste être en mesure de choisir tous les autres résultats. Une compréhension de liste devrait fonctionner parfaitement:

[x for x in s.split('|') if x.startswith('conf/')

Cela itérera sur tous vos résultats. Cependant, le problème est que vous avez encore beaucoup de résultats à la fin qui n'ont pas conf en eux. Vous pouvez ignorer ceux avec une tranche de liste comme

# -2 will grab everything except the last result
s.split('\conf')[:-2]

Ou vous pouvez les ignorer physiquement comme:

[x.split(end)[0] for x in s.split(start) if x]

Je pense que le ce dernier est un peu plus robuste et plus lisible, car pour une application générale de cette logique, je ne garantirais pas l'emplacement des mauvais résultats, et la tranche pourrait supprimer ce que vous voulez réellement.

Donc au total , votre fonction pourrait ressembler à:

s.split(start)
['', 'icdcs/BarbaraGS86|', 'icdcs/ShethL86|', 'icde/BhargavaMRS89|', 'icde/BhargavaNS88|', 'icde/BhargavaR88|', 'icde/ElmagarmidH88|', 'infocom/BadalM84|', 'sigmod/Skeen81|', 'sosp/PresottoM83|', 'vldb/Gray81|journals/cacm/EswarranGLT76|journals/cacm/Lamport78|journals/computer/Alexandridis86|journals/computer/Goguen86|journals/computer/KartashevK86|journals/csur/BernsteinG81|journals/csur/DavidsonG85|journals/csur/Kohler81|journals/jacm/Papadimitriou79b|journals/tc/Avizinis76|journals/tc/Garcia-Molina82|journals/tocs/BirrelN84|journals/tocs/CheritonZ85|journals/tocs/Reed83|journals/tods/Herlihy87|journals/tods/KungR81|journals/tse/BhargavaR89|journals/tse/BlackHJLC87|journals/tse/Randell75|journals/tse/SkeenS83']


0 commentaires