回答:
おそらく、良い方法は、部分文字列を切り取ることです:
String St = "super exemple of string key : text I want to keep - end of my string";
int pFrom = St.IndexOf("key : ") + "key : ".Length;
int pTo = St.LastIndexOf(" - ");
String result = St.Substring(pFrom, pTo - pFrom);
あなたは正規表現なしでそれを行うことができます
input.Split(new string[] {"key :"},StringSplitOptions.None)[1]
.Split('-')[0]
.Trim();
実装の堅牢性/柔軟性に応じて、これは実際には少し難しい場合があります。これが私が使用する実装です:
public static class StringExtensions {
/// <summary>
/// takes a substring between two anchor strings (or the end of the string if that anchor is null)
/// </summary>
/// <param name="this">a string</param>
/// <param name="from">an optional string to search after</param>
/// <param name="until">an optional string to search before</param>
/// <param name="comparison">an optional comparison for the search</param>
/// <returns>a substring based on the search</returns>
public static string Substring(this string @this, string from = null, string until = null, StringComparison comparison = StringComparison.InvariantCulture)
{
var fromLength = (from ?? string.Empty).Length;
var startIndex = !string.IsNullOrEmpty(from)
? @this.IndexOf(from, comparison) + fromLength
: 0;
if (startIndex < fromLength) { throw new ArgumentException("from: Failed to find an instance of the first anchor"); }
var endIndex = !string.IsNullOrEmpty(until)
? @this.IndexOf(until, startIndex, comparison)
: @this.Length;
if (endIndex < 0) { throw new ArgumentException("until: Failed to find an instance of the last anchor"); }
var subString = @this.Substring(startIndex, endIndex - startIndex);
return subString;
}
}
// usage:
var between = "a - to keep x more stuff".Substring(from: "-", until: "x");
// returns " to keep "
InvariantCulture
はWindows Universal Appsと連携していません。クラスの機能を維持したままそれを削除する方法はありますか?@ChaseMedallion
これが私がそれを行う方法です
public string Between(string STR , string FirstString, string LastString)
{
string FinalString;
int Pos1 = STR.IndexOf(FirstString) + FirstString.Length;
int Pos2 = STR.IndexOf(LastString);
FinalString = STR.Substring(Pos1, Pos2 - Pos1);
return FinalString;
}
私はこれがうまくいくと思います:
static void Main(string[] args)
{
String text = "One=1,Two=2,ThreeFour=34";
Console.WriteLine(betweenStrings(text, "One=", ",")); // 1
Console.WriteLine(betweenStrings(text, "Two=", ",")); // 2
Console.WriteLine(betweenStrings(text, "ThreeFour=", "")); // 34
Console.ReadKey();
}
public static String betweenStrings(String text, String start, String end)
{
int p1 = text.IndexOf(start) + start.Length;
int p2 = text.IndexOf(end, p1);
if (end == "") return (text.Substring(p1));
else return text.Substring(p1, p2 - p1);
}
ここで正規表現はやりすぎです。
あなたは可能性が使用string.Split
受け取るオーバーロードでstring[]
区切り文字のためにそれは考えもやり過ぎ。
Substring
andを見てくださいIndexOf
-前者は与えられた文字列の一部とインデックスと長さを取得するためのもので、2番目は内部の文字列/文字のインデックスを見つけるためのものです。
string.Split
。
機能するLINQソリューション:
string str = "super exemple of string key : text I want to keep - end of my string";
string res = new string(str.SkipWhile(c => c != ':')
.Skip(1)
.TakeWhile(c => c != '-')
.ToArray()).Trim();
Console.WriteLine(res); // text I want to keep
string str="super exemple of string key : text I want to keep - end of my string";
int startIndex = str.IndexOf("key") + "key".Length;
int endIndex = str.IndexOf("-");
string newString = str.Substring(startIndex, endIndex - startIndex);
:
と-
は一意であるため、使用できます。
string input;
string output;
input = "super example of string key : text I want to keep - end of my string";
output = input.Split(new char[] { ':', '-' })[1];
または、正規表現を使用します。
using System.Text.RegularExpressions;
...
var value =
Regex.Match(
"super exemple of string key : text I want to keep - end of my string",
"key : (.*) - ")
.Groups[1].Value;
で実行している例。
あなたはそのやり過ぎかどうかを決めることができます。
検証不足の拡張メソッドとして
using System.Text.RegularExpressions;
public class Test
{
public static void Main()
{
var value =
"super exemple of string key : text I want to keep - end of my string"
.Between(
"key : ",
" - ");
Console.WriteLine(value);
}
}
public static class Ext
{
static string Between(this string source, string left, string right)
{
return Regex.Match(
source,
string.Format("{0}(.*){1}", left, right))
.Groups[1].Value;
}
}
以下の拡張メソッドを使用できます。
public static string GetStringBetween(this string token, string first, string second)
{
if (!token.Contains(first)) return "";
var afterFirst = token.Split(new[] { first }, StringSplitOptions.None)[1];
if (!afterFirst.Contains(second)) return "";
var result = afterFirst.Split(new[] { second }, StringSplitOptions.None)[0];
return result;
}
使い方は:
var token = "super exemple of string key : text I want to keep - end of my string";
var keyValue = token.GetStringBetween("key : ", " - ");
私は基本的に仕事をするVijay Singh Ranaからのコードスニペットを使用しました。ただし、にfirstString
既にが含まれている場合、問題が発生しますlastString
。私が欲しかったのは、JSONレスポンスからaccess_tokenを抽出することでした(JSONパーサーが読み込まれていません)。私はfirstString
だった\"access_token\": \"
と私lastString
でした\"
。少し修正してしまいました
string Between(string str, string firstString, string lastString)
{
int pos1 = str.IndexOf(firstString) + firstString.Length;
int pos2 = str.Substring(pos1).IndexOf(lastString);
return str.Substring(pos1, pos2);
}
あなたが1行の解決策を探しているなら、これはそれです:
s.Substring(s.IndexOf("eT") + "eT".Length).Split("97".ToCharArray()).First()
全体の1行のソリューションSystem.Linq
。
using System;
using System.Linq;
class OneLiner
{
static void Main()
{
string s = "TextHereTisImortant973End"; //Between "eT" and "97"
Console.WriteLine(s.Substring(s.IndexOf("eT") + "eT".Length)
.Split("97".ToCharArray()).First());
}
}
あなたはすでにいくつかの良い答えを持っています、そして私が提供しているコードは最も効率的でクリーンなものからはほど遠いことに気づきました。しかし、それは教育目的に役立つかもしれないと思いました。ビルド済みのクラスとライブラリを1日中使用できます。しかし、内部の仕組みを理解しないと、私たちは単に模倣して繰り返し、何も学ぶことはありません。このコードは機能し、他のいくつかのコードよりも基本的または「未使用」です。
char startDelimiter = ':';
char endDelimiter = '-';
Boolean collect = false;
string parsedString = "";
foreach (char c in originalString)
{
if (c == startDelimiter)
collect = true;
if (c == endDelimiter)
collect = false;
if (collect == true && c != startDelimiter)
parsedString += c;
}
parsedString変数に割り当てられた目的の文字列で終了します。前後のスペースもキャプチャされることに注意してください。文字列は、インデックスなどを持つ他の配列と同様に操作できる単なる文字の配列であることを忘れないでください。
気を付けて。
サブストリングペアの複数のオカレンスを処理する場合、RegExなしでは簡単ではありません。
Regex.Matches(input ?? String.Empty, "(?=key : )(.*)(?<= - )", RegexOptions.Singleline);
input ?? String.Empty
引数のnull例外を回避?=
最初のサブストリングを?<=
保持し、2番目のサブストリングを保持RegexOptions.Singleline
部分文字列ペア間の改行を許可します
部分文字列の順序と出現回数が重要でない場合は、この迅速でダーティなものをオプションにすることができます。
var parts = input?.Split(new string[] { "key : ", " - " }, StringSplitOptions.None);
string result = parts?.Length >= 3 ? result[1] : input;
少なくとも、一致する部分文字列が1つもない場合に元の文字列を返すことで、ほとんどの例外を回避します。
いつも言っているように、不可能はありません。
string value = "super exemple of string key : text I want to keep - end of my string";
Regex regex = new Regex(@"(key \: (.*?) _ )");
Match match = regex.Match(value);
if (match.Success)
{
Messagebox.Show(match.Value);
}
System.Text.RegularExpressionsの参照を追加する必要があるRemeber
私が助けてくれたことを願っています。
おそらくこのようなもの
private static string Between(string text, string from, string to)
{
return text[(text.IndexOf(from)+from.Length)..text.IndexOf(to, text.IndexOf(from))];
}
質問が単一の例に関して述べられるとき、あいまいさが必ず存在します。この質問も例外ではありません。
質問の例では、目的の文字列は明確です。
super example of string key : text I want to keep - end of my string
^^^^^^^^^^^^^^^^^^^
ただし、この文字列は、特定の部分文字列が識別される文字列と境界文字列の例にすぎません。次のように表される、一般的な境界文字列を持つ一般的な文字列を検討します。
abc FF def PP ghi,PP jkl,FF mno PP pqr FF,stu FF vwx,PP yza
^^^^^^^^^^^^ ^^^^^
PP
は前の文字列、FF
は次の文字列であり、パーティーハットは照合するサブ文字列を示します。(質問の例でkey :
は、前の文字列と-
次の文字列です。)私はとの前後に単語の境界が続くPP
と想定していFF
ます(そのため、PPA
とFF8
は一致しません)。
党の帽子に反映されている私の仮定は次のとおりです。
PP
前に1つ(または複数)のFF
部分文字列を付けることができますが、存在しても無視されます。PP
1つ以上PP
のs が続く場合FF
、次PP
のは、先行する文字列と後続の文字列の間の部分文字列の一部です。PP
1つ以上FF
のが続く場合PP
、最初のFF
後続PP
は次の文字列と見なされます。ここでの回答の多くは次の形式の文字列のみを扱うことに注意してください
abc PP def FF ghi
^^^^^
または
abc PP def FF ghi PP jkl FF mno
^^^^^ ^^^^^
正規表現、コード構成、またはこの2つの組み合わせを使用して、対象のサブストリングを識別できます。私はどちらのアプローチが最善であるかについては判断しません。対象の部分文字列に一致する次の正規表現のみを提示します。
(?<=\bPP\b)(?:(?!\bFF\b).)*(?=\bFF\b)
私はPCRE(PHP)正規表現エンジンでこれをテストしましたが、正規表現はまったくエキゾチックではないので、.NET正規表現エンジン(非常に堅牢)で動作するはずです。
正規表現エンジンは次の操作を実行します。
(?<= : begin a positive lookbehind
\bPP\b : match 'PP'
) : end positive lookbehind
(?: : begin a non-capture group
(?! : begin a negative lookahead
\bFF\b : match 'FF'
) : end negative lookahead
. : match any character
) : end non-capture group
* : execute non-capture group 0+ times
(?= : begin positive lookahead
\bFF\b : match 'FF'
) : end positive lookahead
前の文字列に続いて、その文字F
が続くまでF
(または、より一般的には、文字が次の文字列を構成する文字列である)、一度に1文字ずつ照合するこの手法は、Tempered Greedy Token Solutionと呼ばれます。
当然のことながら、上で述べた仮定が変更された場合、(可能であれば)正規表現を変更する必要があります。
1.詳細な説明については、カーソルを動かしてください。
C#8.0以降では、次のように範囲演算子..
を使用できます
var s = "header-THE_TARGET_STRING.7z";
var from = s.IndexOf("-") + "-".Length;
var to = s.IndexOf(".7z");
var versionString = s[from..to]; // THE_TARGET_STRING
詳細については、ドキュメントを参照してください。
substring
およびindexof