Извлечь из строки только крайние правые n букв


110

Как я могу извлечь одну, substringсостоящую из шести крайних правых букв, из другой string?

Пример: моя строка "PER 343573". Теперь хочу только извлечь "343573".

Как я могу это сделать?


Вы можете использовать исходный код для метода VB.NET Right. Сначала вам нужно преобразовать в C #: linksource.microsoft.com/#Microsoft.VisualBasic/… Преобразовать в C # с помощью convert.telerik.com
Даррен Гриффит

но код VB основан на функции c # Substring в strings.sc
Наш человек в бананах

На самом деле это не очень хороший способ сделать это, но если вы в затруднении, вы можете добавить ссылку на Microsoft.VisualBasic.dll и использовать правильный метод. Это не метод расширения. Вы должны использовать его так:string endOfString = Strings.Right(wholeString, 6);
Алан МакБи - MSFT

Ответы:


156
string SubString = MyString.Substring(MyString.Length-6);

35
Этот подход не работает правильно, если длина строки меньше требуемого количества символов.
stevehipwell

1
В зависимости от того, что именно хочет OP, можно также использовать регулярные выражения. Если ему нужен только номер в конце строки, это определенно самое безболезненное решение, особенно когда количество цифр может измениться при более позднем обновлении программного обеспечения.
Joey

2
@Johannes Rössel - я большой поклонник регулярных выражений (см. Мои ответы), но я бы никогда не рекомендовал их для такой простой ситуации, как эта. Любой из ответов, в которых используется оболочка функции, лучше подходит для обслуживания кода, чем регулярное выражение. Метод расширения (или стандартная функция, если .NET 2.0) - лучшее решение.
stevehipwell

@ Stevo3000 - наличие решения, которое выдает, если строка имеет неправильную длину, является допустимым решением. Не единственное решение, но все же.
Марк Л.

3
@James - чтобы быть столь же назойливым, только в заголовке упоминается "n букв". Фактически заданный вопрос - это «шесть крайних правых букв» :)
Крис Роджерс

69

Напишите метод расширения для выражения Right(n);функции. Функция должна иметь дело с нулевыми или пустыми строками, возвращая пустую строку, строки короче максимальной длины, возвращающие исходную строку, и строки длиннее максимальной длины, возвращающие максимальную длину крайних правых символов.

public static string Right(this string sValue, int iMaxLength)
{
  //Check if the value is valid
  if (string.IsNullOrEmpty(sValue))
  {
    //Set valid empty string as string could be null
    sValue = string.Empty;
  }
  else if (sValue.Length > iMaxLength)
  {
    //Make the string no longer than the max length
    sValue = sValue.Substring(sValue.Length - iMaxLength, iMaxLength);
  }

  //Return the string
  return sValue;
}

Начальный индекс также не может быть меньше 0.
Джеймс

2
@James - Это будет не так, как sValue.Length > iMaxLengthдо вызова подстроки!
stevehipwell

3
Отличный ответ, но увидеть венгерскую нотацию в коде C # было немного сложно.
Jerad Rose

1
@JeradRose - я работаю в проекте, где кодовая база выросла из приложения VB3 (большая часть этого - VB.NET), поэтому есть некоторые остатки.
Stevehipwell

4
@Jalle, VB.NET имеет Left, Right и Mid в качестве функций верхнего уровня, а также много других полезных вещей, которые не являются частью C #. Не уверен, почему, так как многие из них являются достойными функциями.
ингредиент_15939

40

Наверное, лучше использовать метод расширения:

public static class StringExtensions
{
    public static string Right(this string str, int length)
    {
        return str.Substring(str.Length - length, length);
    }
}

использование

string myStr = "PER 343573";
string subStr = myStr.Right(6);

19
Тогда это вызовет исключение NullReferenceException, как если бы вы попытались использовать какой-либо метод для нулевой строки ...
Джеймс,

1
str.Length - lengthможет быть отрицательным. Также второй параметр не обязателен. Не нужно передавать длину.
iheartcsharp

1
@ JMS10, конечно, может быть, но это больше беспокоит вызывающих абонентов, чем меня. Кроме того, да, честно, вы можете использовать переопределение, которое просто принимает здесь единственный параметр.
Джеймс

str? .Substring (str.Length - длина, длина);
Ludwo

26
using System;

public static class DataTypeExtensions
{
    #region Methods

    public static string Left(this string str, int length)
    {
        str = (str ?? string.Empty);
        return str.Substring(0, Math.Min(length, str.Length));
    }

    public static string Right(this string str, int length)
    {
        str = (str ?? string.Empty);
        return (str.Length >= length)
            ? str.Substring(str.Length - length, length)
            : str;
    }

    #endregion
}

Не должно ошибаться, возвращает нули как пустую строку, возвращает усеченные или базовые значения. Используйте его как "testx" .Left (4) или str.Right (12);


13

MSDN

String mystr = "PER 343573";
String number = mystr.Substring(mystr.Length-6);

РЕДАКТИРОВАТЬ: слишком медленно ...


9

если вы не уверены в длине своей строки, но уверены в количестве слов (в данном случае всегда 2 слова, например, xxx yyyyyy), вам лучше использовать split.

string Result = "PER 343573".Split(" ")[1];

это всегда возвращает второе слово вашей строки.


Да; предположим, что в тексте OP ВСЕГДА есть пробелы; как в его примере :)
Кристиан

1
Привет, Кристиан :) мы все знаем больше, чем пару строчек ответа. Я просто кратко ответил на вопрос, конечно, в реальном коде нужно учитывать гораздо больше вещей.
Махди Тахсильдари

7

Это не совсем то, что вы просите, но просто глядя на пример, кажется, что вы ищете числовую часть строки.

Если это всегда так, то хороший способ сделать это - использовать регулярное выражение.

var regex= new Regex("\n+");
string numberString = regex.Match(page).Value;

Регулярные выражения -1 - это немного излишне для чего-то вроде этого, особенно когда для этого уже есть встроенные методы.
Джеймс

1
Я не выступаю за использование этого метода, если вам действительно нужны только последние 6, но если ваша цель - извлечь число (например, идентификатор), которое в какой-то момент в будущем может измениться на 5 или 7 цифр, это это лучший способ.
chills42

1
Старый ответ, но +1 для поддержки использования регулярных выражений. Тем более, что (до сих пор) нет встроенных методов в реализации String .NET для этого @James. В противном случае этого вопроса, возможно, никогда не существовало.
CrazyIvan1974

@ CrazyIvan1974, не уверен, почему вы упомянули меня в своем комментарии
Джеймс


5

Предполагая ваши требования, но следующее регулярное выражение даст только 6 буквенно-цифровых символов до конца строки и не совпадет в противном случае.

string result = Regex.Match("PER 343573", @"[a-zA-Z\d]{6}$").Value;

Не соответствует ли это решение расплывчатым требованиям? Если нет, объясните свое отрицательное голосование.
Уэйд,

5

Поскольку вы используете .NET, который компилируется в MSIL , просто укажите Microsoft.VisualBasic и используйте встроенный Strings.Rightметод Microsoft :

using Microsoft.VisualBasic;
...
string input = "PER 343573";
string output = Strings.Right(input, 6);

Нет необходимости создавать собственный метод расширения или выполнять другую работу. Результат достигается с помощью одной ссылки и одной простой строки кода.

В качестве дополнительной информации по этому поводу использование методов Visual Basic с C # описано в другом месте . Я лично впервые наткнулся на это при попытке проанализировать файл и обнаружил, что этот поток SO при использовании Microsoft.VisualBasic.FileIO.TextFieldParserкласса чрезвычайно полезен для анализа файлов .csv.


Этот подход также был подробно описан в другом потоке SO здесь: stackoverflow.com/a/15255454/2658159
Аарон Томас

Это МЕНТАЛЬНО! Но, как парню из VB, приятно хоть раз возглавить CSharpers!
SteveCinq

5
var str = "PER 343573";
var right6 = string.IsNullOrWhiteSpace(str) ? string.Empty 
             : str.Length < 6 ? str 
             : str.Substring(str.Length - 6); // "343573"
// alternative
var alt_right6 = new string(str.Reverse().Take(6).Reverse().ToArray()); // "343573"

это поддерживает любое количество символов в str. альтернативный код не поддерживает nullстроку. причем первый быстрее, а второй компактнее.

Я предпочитаю второй, если знаю strсодержащую короткую строку. если это длинная строка, более подходит первая.

например

var str = "";
var right6 = string.IsNullOrWhiteSpace(str) ? string.Empty 
             : str.Length < 6 ? str 
             : str.Substring(str.Length - 6); // ""
// alternative
var alt_right6 = new string(str.Reverse().Take(6).Reverse().ToArray()); // ""

или

var str = "123";
var right6 = string.IsNullOrWhiteSpace(str) ? string.Empty 
             : str.Length < 6 ? str 
             : str.Substring(str.Length - 6); // "123"
// alternative
var alt_right6 = new string(str.Reverse().Take(6).Reverse().ToArray()); // "123"

1
Мне нравится эта альтернатива. Подробно, но легко понять и автоматически решает проблему слишком короткой строки.
Эндрю Гроте

3

Использовать это:

string mystr = "PER 343573"; int number = Convert.ToInt32(mystr.Replace("PER ",""));



3

Нулевые безопасные методы:

Строки короче максимальной длины, возвращая исходную строку

Метод расширения строки справа

public static string Right(this string input, int count) =>
    String.Join("", (input + "").ToCharArray().Reverse().Take(count).Reverse());

Метод расширения строки слева

public static string Left(this string input, int count) =>
    String.Join("", (input + "").ToCharArray().Take(count));

2

Вот решение, которое я использую ... Он проверяет, что длина входной строки не меньше запрошенной длины. Приведенные выше решения, к сожалению, не учитывают это, что может привести к сбоям.

    /// <summary>
    /// Gets the last x-<paramref name="amount"/> of characters from the given string.
    /// If the given string's length is smaller than the requested <see cref="amount"/> the full string is returned.
    /// If the given <paramref name="amount"/> is negative, an empty string will be returned.
    /// </summary>
    /// <param name="string">The string from which to extract the last x-<paramref name="amount"/> of characters.</param>
    /// <param name="amount">The amount of characters to return.</param>
    /// <returns>The last x-<paramref name="amount"/> of characters from the given string.</returns>
    public static string GetLast(this string @string, int amount)
    {
        if (@string == null) {
            return @string;
        }

        if (amount < 0) {
            return String.Empty;
        }

        if (amount >= @string.Length) {
            return @string;
        } else {
            return @string.Substring(@string.Length - amount);
        }
    }

2

Это метод, который я использую: мне нравится все упрощать.

private string TakeLast(string input, int num)
{
    if (num > input.Length)
    {
        num = input.Length;
    }
    return input.Substring(input.Length - num);
}


1
//s - your string
//n - maximum number of right characters to take at the end of string
(new Regex("^.*?(.{1,n})$")).Replace(s,"$1")

Кто-то отметил ваше сообщение для удаления, и я увидел его в очереди на просмотр . Думаю, ваш пост был неправильно отмечен. Ответы, состоящие только из кода, не являются низкокачественными . Пытается ли он ответить на вопрос? Если нет, отметьте. Это технически некорректно? Голосовать против.
Вай Ха Ли,

1
Код должен сопровождаться письменным объяснением того, как он устраняет проблему в OP.
Zze

1
Ну, я думал, что письменного объяснения в комментариях достаточно, не так ли?
vldmrrr

0

Не прибегая к преобразователю битов и сдвигу битов (необходимо быть уверенным в кодировании), это самый быстрый метод, который я использую как метод расширения «Right».

string myString = "123456789123456789";

if (myString > 6)
{

        char[] cString = myString.ToCharArray();
        Array.Reverse(myString);
        Array.Resize(ref myString, 6);
        Array.Reverse(myString);
        string val = new string(myString);
}

2
Array.Reverseпринимает массив, а не строку, и if (myString.length > 6). Если не считать синтаксических ошибок, почему это самый быстрый метод? Конечно, лучше было бы просто использовать подстроку, это не потребовало бы всего этого копирования массивов.
ИНФОРМАЦИЯ 1800

0

Я использую Min для предотвращения негативных ситуаций, а также обрабатываю пустые строки

// <summary>
    /// Returns a string containing a specified number of characters from the right side of a string.
    /// </summary>
    public static string Right(this string value, int length)
    {
        string result = value;
        if (value != null)
            result = value.Substring(0, Math.Min(value.Length, length));
        return result;
    }

0
using Microsoft.visualBasic;

 public class test{
  public void main(){
   string randomString = "Random Word";
   print (Strings.right(randomString,4));
  }
 }

вывод "Word"

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.