10
votes

Couper la corde en Java tout en conservant le mot complet

J'ai besoin de couper une corde en Java afin que:

Le renard brun rapide saute sur le chien laz.

devient

Le brun rapide ...

Dans l'exemple ci-dessus, je coupe à 12 caractères. Si j'utilise simplement la sous-chaîne, j'aurais:

le brit rapide ...

J'ai déjà une méthode pour faire cela en utilisant la sous-chaîne, mais je voulais savoir quelle est la façon la plus rapide (la plus efficace) de le faire car une page peut avoir de nombreuses opérations de garniture.

La seule façon de penser est de diviser la chaîne sur les espaces et de le remettre ensemble jusqu'à ce que sa longueur passe la longueur donnée. Y a-t-il une autre façon? Peut-être une manière plus efficace dans laquelle je peux utiliser la même méthode pour faire une garniture "douce" où je préserve le dernier mot (comme indiqué dans l'exemple ci-dessus) et une bordure dure qui est à peu près une sous-chaîne.

merci,


0 commentaires

7 Réponses :


0
votes

Essayez de rechercher la dernière occurrence d'un espace dans une position inférieure ou supérieure à 11 et coupez la chaîne là-bas, en ajoutant "...".


0 commentaires

11
votes

ci-dessous est une méthode que j'utilise pour couper de longues chaînes dans mes webApps. Le "code doux" boolean comme vous le mettez, si défini sur true préservera le dernier mot. C'est la manière la plus concise de le faire que je pouvais trouver qui utilise une stringbuffer qui est beaucoup plus efficace que de recréer une chaîne qui est immuable. xxx

update

J'ai changé le code de sorte que le ... est ajouté dans la Stringbuffer, il s'agit d'empêcher les créations inutiles de chaîne implicitement qui est lent et gasthful.

Remarque: ESCASSHTML est une importation statique d'Apache Commons:

Importation statique org.apache.commons.lang.stringescapespacetutils.scapehtml;

Vous pouvez le supprimer et que le code doit fonctionner de la même manière.


6 commentaires

Comment Stringbuffer aide à la performance ici? Il n'y a aucune raison pour que substrant , indexof et longueur serait plus rapide sur stringbuffer que sur String < / code>.


Permettez-moi de vous clarifier, l'astituant a dit que c'était une toicheuse, puis mettait la ficelle ensemble. Chaque fois qu'il ajoute un nouveau jeton sur la chaîne de la chaîne entière est détruite et recréée. Pour les chaînes longues, cette opération est beaucoup plus chère que d'utiliser un Stringbuffer . Bien que je suis d'accord, la différence de performance est probablement négligeable en considérant que le Stringbuffer


Le problème est que dans votre code, vous n'appelez rien à Stringbuffer .


Merci, vous êtes absolument correct que les points doivent être annexés dans les Stringbuffer à tout le moins. Je vais mettre à jour ma réponse après avoir testé l'assurez-vous qu'il n'y a pas de bugs.


@Trandinhthoai Escalyhtml est une importation statique. Importer static org.apache.commons.plang.stringsescapetitils.scapehtml; Vous pouvez le supprimer, il fonctionnera de la même manière. Je l'ai là car je l'utilise dans une webApp et je dois échapper aux entités HTML.


@Ali il ne vaut toujours pas la peine d'utiliser Stringbuffer ici. Concaténant seulement deux chaînes est peu susceptible d'être plus rapide que + . Dans les deux cas, vous faites presque la même chose.



0
votes

Vos exigences ne sont pas claires. Si vous avez du mal à les articuler dans une langue naturelle, il n'est pas surprenant qu'ils soient difficiles à traduire dans une langue d'ordinateur comme Java.

"Conserver le dernier mot" implique que l'algorithme saura ce qu'est un "mot", vous devrez donc le dire d'abord. La scission est un moyen de le faire. Un scanner / analyseur avec une grammaire en est un autre.

Je crains de le faire fonctionner avant que je me préoccupe d'efficacité. Faites-le travailler, mesurez-le, puis voyez ce que vous pouvez faire sur la performance. Tout le reste est la spéculation sans données.


1 commentaires

Assez juste. Qu'est-ce que je voulais dire par "conserver le dernier mot" est que je ne veux pas tronquer une corde sur aucun caractère sauf un espace blanc? Cela a-t-il du sens?



0
votes

Que diriez-vous:

mystring = mystring.replaceAll("^(.{12}.*?)\b.*$", "$1...");


3 commentaires

Pouvez-vous expliquer la regex? Cela préserverait-il le dernier mot ou non? Votre regex est différent de Bohemian.


Prenez les 12 premiers caractères et le minimum après cela pour compléter le mot, et ajouter ...


J'ai effectivement oublié d'ajouter quelque chose à la fin du motif pour supprimer le reste de la chaîne. Éditer maintenant pour réparer.



9
votes

Voici une solution simple, basée sur les regex, 1 ligne basée sur la regex: xxx pré>

explication: p>

  • (? est un look négatif derrière em>, qui affirme qu'il y a au moins 12 caractères à gauche du match, mais est une correspondance non capture (c'est-à-dire zéro) li>
  • \ b. * code> correspond à la première limite de mot (après au moins 12 caractères - ci-dessus) à la fin li> ul>

    Ceci est remplacé par "..." p>

    Voici un test: p> xxx pré>

    sortie: p>

    String trimmed = pattern.matcher(input).replaceAll("...");
    


6 commentaires

Pouvez-vous expliquer la regex? J'aime la solution, même si je devais voir comment il empilète une vitesse sage sur la réponse d'Ali ci-dessous.


@Amzfr n'utilise pas regex si vous vous inquiétez de la vitesse. Cela va être beaucoup plus lent que indexof + sous-chaîne (10-100 fois plus lent).


Merci @Banthar, je m'appuyais simplement parce que j'aime bien savoir ce qui se passe dans le code, la solution de regex est toujours élégante.


Une belle réponse. Solution plus simple pour quand la performance n'est pas un facteur premier


@SAIFASIF J'ai ajouté une version plus rapide si la performance est requise, bien que la version d'origine n'exécuteait que quelques microsecondes, alors que si vous aviez besoin de cela pour courir vraiment très vite, je favoriserais la doublure sur la compilation statique de la regex.


Oui, j'ai vu, je l'ai marqué et j'ai trouvé une passe de 33 ms par jeton, qui sera honnête, c'est assez bon pour mon cas d'utilisation!



5
votes

Veuillez essayer le code suivant: xxx


1 commentaires

C'est bien et simple. Merci!



0
votes

J'utilise ce piratage: supposons que la chaîne coupée doit avoir 120 de longueur: xxx


0 commentaires