11
votes

Comment remplacer les onglets personnalisés avec des espaces dans une chaîne dépend de la taille de l'onglet?

J'essaie d'écrire une fonction Python qui n'utilise aucun modules qui prendront une chaîne qui comporte des onglets et remplacera les onglets avec des espaces appropriés pour une taille de TabSTop entrées. Il ne peut pas simplement remplacer tous les onglets Taille-N par N espaces, car un onglet pourrait être de 1 à N espaces. Je suis vraiment confus, alors si quelqu'un pouvait me signaler dans la bonne direction, je l'apprécierais grandement.

Par exemple, Si TABSTOP est la taille 4 à l'origine: xxx

mais modifié en tabstop 5: xxx

Je pense que j'ai besoin de tamponner le Fin de la chaîne avec des espaces jusqu'à ce que string% n == 0 puis je le déchaîne, mais je suis assez perdu pour le moment ..


5 commentaires

Voulez-vous "_" pour chaque onglet (\ t)?


Ce serait une bonne idée d'ajouter un tas de cas de test à votre question


Ce qui se passe si obstiné est 5 et que la chaîne est plus longue, par exemple 123456 \ t? Le résultat est le suivant: 1234_56___? 1234_6____? 123456_?


Il me manque peut-être quelque chose, mais un tabeur n'est pas une taille "n". Un tabstop est \ t qui est un caractère et est toujours taille 1. Voulez-vous remplacer les espaces avec des onglets, peut-être? Ou des espaces avec moins d'espaces?


Ohhhhh. D'accord. Je vois ce que tu veux dire. Vous devriez probablement reformuler votre question car c'est un peu déroutant au début.


12 Réponses :


2
votes

Désolé, j'ai mal interprété la question la première fois.

Ceci est une version récursive qui devrait fonctionner pour n'importe quel nombre d'onglets dans l'entrée: P>

def tabstop ( s , tabnum = 4):
    if not '\t' in s:
        return s
    l = s.find('\t')
    return s[0:l]+' '*(tabnum-l)+tabstop(s[l+1:],tabnum)


0 commentaires

4
votes

Puisque vous n'êtes pas une fonction Python qui n'utilise aucun module externe, je pense que vous devriez concevoir d'abord l'algorithme de votre fonction ...

Je proposerais de itérer sur chaque char de la chaîne; Si vous êtes un onglet, vous devez calculer combien d'espaces à insérer: l'index "aligné" suivant est ((i / tabstop) + 1) * Tabstop. Vous devez donc insérer ((i / tabstop) + 1) * Tabstop - (I% Tabstop). Mais un moyen plus facile est d'insérer des onglets jusqu'à ce que vous soyez aligné (i.e. i% tabstop == 0) xxx


6 commentaires

Merci à tous pour votre aide. C'est exactement ce que je cherchais, j'avais juste un bloc mental essayant de m'envoyer mon esprit autour de l'algorithme, alors merci encore!


Quelqu'un sait comment changer cela pour travailler avec plusieurs onglets d'affilée? Semble qu'il ne ramasse que le premier


Dans le test, j'ai exécuté plusieurs onglets étaient OK: replace_tab ('123 \ t12 \ t1 \ t123456 \ t1234 \ t12345678 \ n') renvoie '123.12..11 ... 123456..123412345678' (avec points de remplacement des espaces pour la lisibilité)


BTW, je pense que d'autres réponses avec la compréhension de la liste, Split et Join sont beaucoup plus élégantes ...


Pour plusieurs onglets comme "uint8_t \ t \ tvalue;" J'ai inséré "si len (résultat)% tabstop == 0: résultat + = ''" avant la boucle tandis que.


Cela ne devrait pas être soulevé car il est incorrect - je doute que c'était déjà testé. Un onglet de premier plan est simplement jeté, remplacé par rien. (Et seul le premier onglet est remplacé, bien que cette fonctionnalité négative soit documentée.)



1
votes

Ce code peut vous aider:

initial_string = "My \tstring \ttest\t"
block_size = "5"
"".join([("{block_value:"+str(block_size)+"s}").format(block_value=block) 
    for block in initial_string.split("\t")])


0 commentaires

5
votes

Pour une longueur d'onglet de 5:

>>> s = "123\t123"
>>> print ''.join('%-5s' % item for item in s.split('\t'))
123  123  
>>> 


1 commentaires

Ou: (5 * '') .join (s.split ('\ t'))



1
votes

Ce programme remplace tous les onglets des espaces dans un fichier: xxx


0 commentaires

0
votes

J'avais besoin de quelque chose de similaire, voici ce que j'ai proposé:

import re

def translate_tabs(tabstop = 8):
  offset = [0]
  def replace(match, offset=offset):
    offset[0] += match.start(0)
    return " " * (tabstop - offset[0] % tabstop)
  return replace

re.sub(r'\t', translate_tabs(4), "123\t123") 
# => '123 123'

re.sub(r'\t', translate_tabs(5), "123\t123")
# => '123  123'


0 commentaires

2
votes

Je pense que la réponse de Rémi est la plus simple, mais elle a un bogue, il ne tient pas compte du cas lorsque vous êtes déjà sur une colonne "Tabarron". Tom Swirly l'a signalé dans les commentaires. Voici une solution testée à sa suggestion: xxx


0 commentaires

4
votes

J'utilise la fonction .replace qui est très simple: xxx


0 commentaires

0
votes

Utiliser le repère suffit.

def untabify(s, tabstop = 4):
    return re.sub(re.compile(r'\t'), ' '*tabstop, s)


0 commentaires

1
votes

Si vous avez la condition où vous souhaitez ajouter N espaces au lieu de l'onglet personnalisé Vous pouvez simplement écrire ci-dessous le code. J'ai montré la mise en œuvre à l'aide de deux fonctions, chacune ayant une manière différente de le résoudre. Vous pouvez utiliser l'une des fonctions!

pour par exemple. Laissez la chaîne être dans la variable 'code' et 'x' être la taille de l'onglet xxx

Les deux fonctions ci-dessus donneront la même valeur, mais le second est super génial!


0 commentaires

1
votes

Voici le moyen le plus simple xxx


0 commentaires

0
votes

Correction pour @ réj Cette implémentation honore l'onglet principal et tout onglets consécutifs xxx


0 commentaires