2012-05-30 6 views
1

Есть некоторые текстовые файлы, которые мне нужны, чтобы разбить отдельные слова. Но с очень либеральным определением слова.Regex To Parse Anything Not A b

\b, кажется, правильно идентифицирует границы, но так как это нулевая ширина^\ b ничего не делает.

Я знаю, что .NET string.parse может быть быстрее, но мне нужна позиция соответствия.

В чем я оказался, показано ниже. Когда с^на ненулевом, что я хотел разрываться. Добавлена ​​дата, адрес электронной почты и URL, которые хотели игнорировать перерывы.

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

String line; 
pattern = @"\[email protected]\w+|[01]?\d\/[0123]?\d\/([12]\d)?\d\d|https?:\/\/(?:\w+\.){1,3}\w+|[^\s\.\\///?!()@,]{2,200}"; 
    while ((line = sr.ReadLine()) != null) 
    { 
     Debug.WriteLine(line); 
     foreach (Match match in Regex.Matches(line, pattern, RegexOptions.IgnoreCase)) 
     { 
      Debug.WriteLine(match.Index.ToString() + " " + match.Value); 
     } 
     break; 
    } 
+1

Пожалуйста, добавьте образец строки и нужные совпадения. –

+0

@ChrisS, который до 75 пустых. Количество символов в строке. pattern = @ "\ b ([^ \\ b] +) \ b"; дал странный анализ 3 слов на границах слов, но некоторые слова включали границы работы. – Paparazzi

+0

Вы, например, говорите, что хотите 'MSCFX package propertiescu3u bin exet [p" R'4 ~ fd' из строки мусора, но разве это не вся целая строка мусора? –

ответ

1

Словесность слова \B не относится к смежным элементам того же слова, слова или слова, содержащего слово.

Вы, кажется, хотите \b(\w+|\W+)\b, потому что ((?:\B.\B)+) оставит конечные символы одного и того же.

редактировать:

Re обновить ..

You could split with this [^\p{L}] *\p{Z} [^\p{L}]* or use 

(dosen't account for graphines) 
[\s\pP]* ([\pL\pN_-] (?: [\pL\pN_-] | \pP(?=[\pL\pN\pP_-]))*) 
    or 
[\s[:punct:]]* (\w (?: \w | [[:punct:]](?=[\w[:punct:]]))*) 

Оба дают

'hello' 
'world' 
'MSCFX' 
'package.propertiescu3u' 
'bin\exet[p"R4~fd' 
'Would' 
'like' 
'MSCFX' 
'package' 
'propertiescu3u' 
'bin' 
'centra' 
'exet[p"R4~fd' 
+0

\ W + соответствует символам \ b. См. Обновление, чтобы ответить. – Paparazzi

+0

Я ценю вашу помощь, но не следую «split with» pattern = @ "[^ \ p {L}] * \ p {Z} [^ \ p {L}] *"; выводит всю строку – Paparazzi

+0

Выньте места. '@ "[^ \ Р {L}] * \ р {Z} [^ \ р {L}] *"'. Будьте осторожны, это даст другой результат, чем другие два регулярных выражения. – sln

1

\w соответствует буквы, цифры и _ (подчеркивание). \b соответствует границам между \w и \W (символы без слов, [^\w]). \B граница (всегда нуль-ширина), поэтому \B+ бессмысленно.

Редактировать: У меня все еще есть проблемы с пониманием того, где вы хотите разбить слова.

Если вы хотите, чтобы соответствовать ничего, кроме . (период) и пробельных, попробуйте этот исключения метод:

[^.\s]+ 

Если вы хотите включить определенные символы, попробуйте это включение метод:

[-\w`[email protected]#$%^&*\[\]()\\\/]+ 
+0

Спасибо, но \ S + не является достаточно либеральным парсером. \ b будет анализироваться. \ – Paparazzi

+0

Обновлен вопрос спасибо. – Paparazzi

+0

@Blam, не уверен, что я все еще понимаю, но у вас в значительной степени есть два варианта, включение и исключение ... см. Мое редактирование. –

1

Почему не просто разделить строку на пробелы, символы обратной косой черты, и периоды, как в вашем пример?

// C# 
string str = "MSCFX package.propertiescu3u bin\\exet[p\"R`4~fd"; // note the necessary escapes for \ and " 
var words = Regex.Split(str,@"[ \.\\]"); // split on spaces, periods, and backslashes 
+0

См. Заявление о проблеме «Я знаю, что .NET string.parse может быть быстрее, но мне также нужна позиция соответствия». – Paparazzi

1

Необходимо точно понимать, что такое \b. Имейте в виду, что регулярные выражения не могут читать; «слово» в «границе слова» произвольно определяется как одна или несколько букв, цифр или символов подчеркивания. Если ваше определение отличается, \b бесполезно.

Так что же именно вы считаете слово? Глядя на ваш обновленный вопрос, я до сих пор не вижу полезного шаблона. Вы просто хотите разделить пробелы и периоды?

pattern = @"(?<=^|[\s.])[^\s.]+(?=[\s.]|$)"; 

Применительно к тестовой строки:

MSCFX package.propertiescu3u bin\exet[p"R`4~fd 

... это соответствует:

MSCFX 
package 
propertiescu3u 
bin\exet[p"R`4~fd 
+0

Слово - это что-то, что не \ b. Это так просто.Каждый персонаж является либо перерывом, либо частью слова. – Paparazzi

+0

Нет, это не так просто: «ничего, что не является \ b» не имеет смысла. Если вы не можете найти более четкий набор критериев, то вы не сможете это сделать с помощью регулярного выражения. –

+1

Я согласен, что \ b не имеет смысла. У меня было неправильное понимание \ b. Извините – Paparazzi

1

Согласно RegexHero

([^\\b]*) 

Работы MSCFX package.propertiescu3u bin\exet[p"R``4~fd с использованием ignorecase, singleline.

enter image description here

+0

'[^ \ b]' соответствует любому символу, кроме backspace. '\ b' теряет свой нормальный смысл в классе символов). Противоположностью '\ b' является' \ B', но они оба утверждения с нулевой шириной: они не потребляют никаких символов, когда они совпадают. –

+0

@AlanMoore на самом деле там \\ b там, SO удалял его –

+0

Это все еще не так. '[^ \\ b]' соответствует любым символам, кроме '' '' '' '' или 'b'. Во всяком случае, я уверен, что OP хочет сопоставить четыре «слова» внутри этой строки, а не всю строку сразу. –

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