2015-05-06 2 views
6

У меня есть текст, как это:Regex чтобы выбрать часть слова

my text has $1 per Lap to someone. 

Может кто-нибудь сказать мне, как выбрать per часть из него. Я знаю, как выбрать сумму $. Это примерно так:

new Regex(@"\$\d+(?:\.\d+)?").Match(s.Comment1).Groups[0].ToString() 

Любая помощь будет высоко оценена.

+0

Чтобы уточнить: вы хотите, чтобы соответствовать '' $, число, 'per', и слово; фиксируя число и слово? – Richard

+0

Какой тип 'per'? – Kasramvd

+0

@ Kasra это просто тип строки. – Sampath

ответ

1

Как вы сказали, что per является строка введите следующее простое регулярное выражение может делает работу для вас:

\$\d+\s([a-zA-Z]+) 

Но если per является содержать цифры, которые можно использовать \w, которые соответствуют символам слова:

\$\d+\s(\w+) 

Demo

Примечание, что в этом случае per находится в первой группе захвата, и вам нужно извлечь первую группу.

Также вы можете использовать позитивный взгляд позади, если вы не хотите использовать grouping:

(?<=\$\d+\s)[a-zA-Z]+ 

Если per это специальное слово, которое вы можете проверить с следующим регулярным выражением:

(?<=\$\d+\s)per 

что-то вроде :

var per_str = new Regex(@'(?<=\$\d+\s)per').Match(str).Groups[0].Value; 
if (per_str != ''){ 
#dostuff 
} 
+0

На вашей демонстрации, где я увидел, что она выбирает как '' '' '' '' '' '' '' '' '' '.Не нужно выбрать только' per' часть. – Sampath

+0

@Sampath Да, это ваш матч, так как вы используете группировку захвата, вам нужно извлечь первую группу. 'Match (s.Comment1) .Groups [1]' – Kasramvd

+0

@Sampath Checkout редактирование для альтернативного пути! – Kasramvd

0
(?<=\$\d+(?:\.\d+)?\s+)\S+ 

Это должно сделать это за вас.

2

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

Чтобы получить per часть, используйте следующее регулярное выражение и захватить Groups[2].Value:

var str = "my text has $1 per Lap to someone. "; 
var per_str = new Regex(@"(\$\d+(?:\.\d+)?)\s*(\p{L}+)").Match(str).Groups[2].Value; 

Выход:

enter image description here

Регулярное выражение для захвата per является \p{L}+ где \p{L} захватывает все буквы Unicode (например, ф, ё), а не только латинский алфавит.

Чтобы получить номер детали, использовать тот же регулярное выражение, но захватить Groups[1].Value:

var num_str = new Regex(@"(\$\d+(?:\.\d+)?)\s*(\p{L}+)").Match(str).Groups[1].Value; 

Выход:

enter image description here

И еще один совет: скомпилировать регулярное выражение первым, если вы планируете использовать его несколько раз во время выполнения вашего приложения:

var rx = new Regex(@"(\$\d+(?:\.\d+)?)\s*(\p{L}+)", RegexOptions.Compiled); 
var per_str = rx.Match(str).Groups[2].Value; 
var num_str = rx.Match(str).Groups[1].Value; 

В случае, если вам нужно только число после $, просто положите круглый кронштейн после него в регулярное выражение: @"\$(\d+(?:\.\d+)?)\s*(\p{L}+)".

И получить все группы в 1 ход, вы можете использовать

var groups = rx.Matches(str).Cast<Match>().Select(p => new { num = p.Groups[1].Value, per = p.Groups[2].Value }).ToList(); 

enter image description here

EDIT:

Если вы просто хотите, чтобы соответствовать per после номера, вы можете использовать @"(\$\d+(?:\.\d+)?)\s*(per)" или (без учета регистра) @"(\$\d+(?:\.\d+)?)\s*((?i:per\b))"

+0

Но он выбирает не только «за» других. Это похоже на это. Скажем, у меня есть такой текст, как «мой текст имеет 1 доллар для кого-то». Затем он выбирает 'to'. Как я могу избежать выбрать других? Заранее спасибо. – Sampath

+1

Используйте литерал «per»: '@" (\ $ \ d + (?: \. \ D +)?) \ S * (per) \ b "'. Тем не менее, я не вижу смысла в группе захвата, тогда, поскольку вы знаете, что это «за». Если это не может быть в нижнем или верхнем регистре. Затем используйте '@" (\ $ \ d + (?: \. \ D +)?) \ S * ((? I: per) \ b) ". –

+0

Большое спасибо за вашу поддержку :) – Sampath

0

Как сказал @Sayse, здесь вам не нужно Regex. Я сделал два решения без.

Проверьте Demo или прочитать код:

public static void Main() 
{ 
    var s = "my text has $1 per Lap to someone."; 

    Console.WriteLine(Test(s)); 
    Console.WriteLine(Test2(s)); 
} 

static object Test(string s) 
{   
    var tab = s.Remove(s.IndexOf(" Lap"))  // remove everything after " Lap" 
       .Substring(s.IndexOf(" $") + 2) // remove everything before " $" 
       .Split(' '); 

    return new { Amount = tab[0], Per = tab[1] }; 
} 

static object Test2(string s) 
{ 
    var tab = s.Split(' '); 
    var amount = tab.Single(t => t.StartsWith("$")).Substring(1); 
    var per = tab[Array.FindIndex(tab, t => t.StartsWith("$")) + 1]; 

    return new { Amount = amount, Per = per }; 
} 

выход

{ Amount = 1, Per = per } 
{ Amount = 1, Per = per } 
+1

Да, как я уже сказал, вместо 3 строк у нас есть gazillion. –

+0

В 'Test()' есть только 2 строки, и вы можете сделать это только в одном, если вы сразу возвращаете массив 'tab'. – aloisdg

Смежные вопросы