Витягніть лише рядки з правої частини більшості n рядків


110

Як я можу витягнути з іншого, substringякий складається з найправіших шести літер, з іншого string?

Наприклад: мій рядок є "PER 343573". Тепер я хочу лише витягнути "343573".

Як я можу це зробити?


Ви можете використати вихідний код для методу VB.NET Right. Вам потрібно буде перетворитись на C # спершу: referenceource.microsoft.com/#Microsoft.VisualBasic/… Перетворити на C # за допомогою converter.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
Залежно від того, чого саме хоче ОП, можна також наводити регулярні вирази на це. Якщо s - він бажає лише число в кінці рядка, це, безумовно, найбільш безболісне рішення, особливо коли кількість цифр може змінюватися в процесі подальшого оновлення програмного забезпечення.
Joey

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

@ Stevo3000 - рішення, яке викидає, якщо рядок неправильної довжини, є правильним рішенням. Не єдине рішення, але все ж.
Марк Л.

3
@James - настільки ж розбещений, лише назва зазначала «п літери». Справжнє поставлене запитання попросило «найправіші шість літер» :)
Кріс Роджерс

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 # коді.
Джерад Роуз

1
@JeradRose - Я працюю в проекті, де база коду перетворилася на додаток VB3 (більша частина цього - VB.NET), тому є залишки.
stevehipwell

4
@Jalle, VB.NET має функції лівого, правого та середнього рівня як функції вищого рівня, а також багато інших корисних речей, які не входять до 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);

EDIT: занадто повільно ...


9

якщо ви не впевнені в довжині рядка, але ви впевнені в кількості слів (завжди в цьому випадку 2 слова, як-от "xxx yyyyyy"), краще використовувати розділення.

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

це завжди повертає друге слово вашого рядка.


Так; давайте просто припустимо, що в тексті ОП ЗАВЖДИ є пробіли; як у його прикладі :)
Крістіан

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

7

Це не зовсім те, про що ви просите, але лише дивлячись на приклад, видається, що ви шукаєте числовий розділ рядка.

Якщо це завжди так, то хорошим способом зробити це буде використання регулярного виразу.

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

-1 регулярні вирази є трохи зайвим для чогось подібного, особливо коли вже є вбудовані методи для цього.
Джеймс

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

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

@ CrazyIvan1974 не впевнений, чому ти згадав мене у своєму коментарі
Джеймс

5

Використовуй це:

String text = "PER 343573";
String numbers = text;
if (text.Length > 6)
{
    numbers = text.Substring(text.Length - 6);
}

текст? .Substring (text.Length - 6)
Ludwo

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

Ще одне рішення, про яке можна не згадати

S.Substring(S.Length < 6 ? 0 : S.Length - 6)

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")

Хтось позначив вашу публікацію для видалення, і я побачив її у черзі на огляд . Я думаю, що ваш пост було позначено неправильно. Відповіді лише для коду неякісні . Чи намагається відповісти на запитання? Якщо ні, прапор Це технічно неправильно? Downvote.
Вай Ха Лі

1
Кодекс повинен супроводжуватися письмовим поясненням щодо того, як він фіксує питання в ОП.
Zze

1
Ну, я вважав, що пояснень у коментарях достатньо, ні?
vldmrrr

0

Не вдаючись до бітового перетворювача та зсуву бітів (потрібно бути впевненим у кодуванні), це найшвидший метод, який я використовую як метод розширення «Правильно».

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.