mboost-dp1

Er du regex "haj"?


Gå til bund
Gravatar #1 - milandt
20. dec. 2012 15:51
Jeg sidder og pusler med en metode der kan splitte et ord i camelcase op i flere ord. Jeg er lidt kørt fast i forhold til hvor jeg gerne vil hen. Gode ideer værdsættes :)

public static string SplitCamelCase(input)
{
string[] arrStr =
Regex.Split(input, @"(?<!^)(?=[A-Z])");
return string.Join(" ", arrStr);
}


Input:
Test
TestTest
TestTest123
TestTest123Test
TestTest1Test2Test3Test
TestTestTESTTest


Nuværende output:
Test
Test Test
Test Test123
Test Test123 Test
Test Test1 Test2 Test3
Test Test T E S T Test


Ønsket output:
Test
Test Test
Test Test 123
Test Test 123 Test
Test Test 1 Test 2 Test 3 Test
Test Test TEST Test
Gravatar #2 - arne_v
20. dec. 2012 16:17
For at drille dig har jeg valgt Java fremfor C#!


import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CamelSplitTest {
private static Pattern re = Pattern.compile("([A-Z][a-z]+)|([A-Z]+(?=([A-Z][a-z]|[0-9]|$)))|([0-9]+)|(^[a-z]+)");
public static List<String> camelSplit(String s) {
List<String> res = new ArrayList<String>();
Matcher m = re.matcher(s);
while(m.find()) {
res.add(m.group());
}
return res;
}
public static void test(String s) {
List<String> parts = camelSplit(s);
System.out.print(s + " ->");
for(String part : parts) System.out.print(" " + part);
System.out.println();
}
public static void main(String[] args) {
String[] all = { "Test", "TestTest", "TestTest123", "TestTest123Test", "TestTest1Test2Test3Test", "TestTestTESTTest", "testTest" };
for(String one : all) {
test(one);
}
}
}


Test -> Test
TestTest -> Test Test
TestTest123 -> Test Test 123
TestTest123Test -> Test Test 123 Test
TestTest1Test2Test3Test -> Test Test 1 Test 2 Test 3 Test
TestTestTESTTest -> Test Test TEST Test
testTest -> test Test



Gravatar #3 - kasperd
20. dec. 2012 16:17
Hvis jeg har forstået dine ønsker rigtigt, så ønsker du at splitte mellem to tegn, hvis de opfylder et følgende:
- Bogstav efterfulgt af ikke bogstav
- Ikke bogstav efterfulgt af bogstav
- Lille bogstav efterfulgt af stort bogstav
- Stort bogstav efterfulgt af stort bogstav og lille bogstav

Kan du ikke blot skrive en regex med de fire kriterier adskilt af |?
Gravatar #4 - arne_v
20. dec. 2012 16:22
#2

Ja - jeg valgte at skifte fra split til match.
Gravatar #5 - milandt
20. dec. 2012 16:23
#3 jo, det er muligvis præcis det jeg skal gøre. jeg er blot ikke særlig stærk i regex. jeg kunne godt tænke mig hvis der fandtes en pseudo-kode-til-regex-oversætter et sted.

#2 java ligefrem :) jeg skal straks se om jeg kan putte det ind i min c# applikation.
Gravatar #6 - arne_v
20. dec. 2012 16:57
#5

Koden kan porteres 1:1 til C#:


using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace E
{
public class Program
{
private static Regex re = new Regex("([A-Z][a-z]+)|([A-Z]+(?=([A-Z][a-z]|[0-9]|$)))|([0-9]+)|(^[a-z]+)", RegexOptions.Compiled);
public static List<string> CamelSplit(string s) {
List<String> res = new List<String>();
MatchCollection mc = re.Matches(s);
foreach(Match m in mc)
{
res.Add(m.Value);
}
return res;
}
public static void Test(string s) {
List<string> parts = CamelSplit(s);
Console.Write(s + " ->");
foreach(string part in parts) Console.Write(" " + part);
Console.WriteLine();
}
public static void Main(string[] args)
{
string[] all = { "Test", "TestTest", "TestTest123", "TestTest123Test", "TestTest1Test2Test3Test", "TestTestTESTTest", "testTest" };
foreach(string one in all)
{
Test(one);
}
Console.ReadKey();
}
}
}

Gravatar #7 - milandt
20. dec. 2012 17:09
Tusind tak. Fik det til at virke i c# (før jeg så din c# udgave)

public static string[] SplitCamelCase(this string str)
{
var re = new Regex("([A-Z][a-z]+)|([A-Z]+(?=([A-Z][a-z]|[0-9]|$)))|([0-9]+)|(^[a-z]+)");
var res = new List<String>();
var m = re.Match(str);

while (m.Success)
{
res.Add(m.Value);
m = m.NextMatch();
}

return res.ToArray();
}
Gravatar #8 - arne_v
20. dec. 2012 17:11
milandt (5) skrev:
jeg kunne godt tænke mig hvis der fandtes en pseudo-kode-til-regex-oversætter et sted.


Jeg tror at den kommer året før compileren som scanner krav spec og outputter MSIL eller Java byte code.

:-)
Gravatar #9 - arne_v
20. dec. 2012 17:12
#7

Der er tid mere end en måde at kode det på.
Gravatar #10 - milandt
20. dec. 2012 17:13
I al fald tak for hjælpen. Much appreciated.

Kan godt li at løse problemer, også inden for områder som jeg ikke har så meget rerfaring med, men regex bliver jeg aldrig rigtig gode venner med.
Gravatar #11 - arne_v
20. dec. 2012 17:49
#10

Regex er en af de ting som man enten kan lide eller ikke kan lide.

Men det er også en af de ting som man skal kende som programmør.

Ligesom XPath, SQL etc..
Gravatar #12 - arne_v
20. dec. 2012 17:57
#11

Jeg har iøvrigt for nyligt i et andet forum set en foreslå en fluent syntax for regex.

Forsimplet:

Regex re = new Regex(Regex.UpperCase)
.FollowedBy(Regex.LowerCase.OneOrMore())
.Or(Regex.Digits.OneOrMore());

Ja - jeg tror det var mest tiltænkt som en joke.
Gravatar #13 - kasperd
20. dec. 2012 18:36
arne_v (11) skrev:
Regex er en af de ting som man enten kan lide eller ikke kan lide.
Regulære sprog er et så fundamentalt koncept, at der ikke er nogen vej udenom det.

Hvilken syntaks de bedst udtrykkes i er der til gengæld delte meninger om. Jeg har hidtil stødt på tre vidt forskellige syntakser for regulære sprog.
#?.info
.*\.jpeg
!(*~)
Ovenstående tre eksempler gør selvfølgelig ikke det samme.

arne_v (12) skrev:
Regex re = new Regex(Regex.UpperCase)
.FollowedBy(Regex.LowerCase.OneOrMore())
.Or(Regex.Digits.OneOrMore());

Ja - jeg tror det var mest tiltænkt som en joke.
Det ville være en joke, hvis man skulle bruge sådan en syntaks til selv de mest simple regulære udtryk. Men hvis man kan skrive simple udtryk med en af de velkendte notationer og så sætte de simple udtryk sammen til større udtryk vha. de konstruktioner, du skitserer, så ville det nok give et langt mere læsbart resultat.
Gravatar #14 - arne_v
20. dec. 2012 18:58
#13

Perl syntaksen er vel blevet de facto standard.
Gravatar #15 - kasperd
20. dec. 2012 19:33
arne_v (14) skrev:
Perl syntaksen er vel blevet de facto standard.
Det er nok også den der har flest features. Til gengæld synes jeg det er den mindst læselige af de tre jeg nævnte.
Gravatar #16 - arne_v
20. dec. 2012 19:59
#15

Og der findes faktisk en POSIX standard (forskellene på den og Perl er ikke så store, men de er der).

Men folket har valgt.
Gravatar #17 - kasperd
20. dec. 2012 21:29
arne_v (16) skrev:
Og der findes faktisk en POSIX standard (forskellene på den og Perl er ikke så store, men de er der).
Jeg har kendskab til forskellige varianter med forskelle i hvornår man bruger \. Der er tegn som har en speciel betydning med mindre de escapes med \, men i den anden version er det modsat for nogle tegn, som skal escapes for at have en speciel betydning.

Et godt regex library kunne sagtens have funktioner til at konvertere strenge fra hvert af de forskellige formater til regex objekter og funktioner som kan kombinere regex objekter til nye regex objekter.
Gravatar #18 - dub
21. dec. 2012 00:52
Get a room. ;)
Gravatar #19 - milandt
21. dec. 2012 08:13
arne_v (12) skrev:
Jeg har iøvrigt for nyligt i et andet forum set en foreslå en fluent syntax for regex.
Det var da ikke helt dumt, men ja, nok en joke, og ville uanset hvad kun kunne bruges i forholdsvis simple udtryk.

Både xpath og sql er "lettere at læse" end regex. Den oprindelige tanke med sql var netop at det skulle være let at læse, nærmest opbygget som en sætning. Det kunne man savne lidt i regex.
Gravatar #20 - fidomuh
21. dec. 2012 08:27
#12

Eller blot en der bruger Perl :P
Gravatar #21 - fidomuh
21. dec. 2012 08:29
#16

Skyldes ikke lidt at baade PHP, C# og Java valgte at implementere efter Perl-Regex og POSIX kun var standard i C, or so?

Det er i hvert fald laenge siden jeg har set nogen bruge POSIX Regex, som IKKE arbejdede (stort set) udelukkende i ren C :D
Gravatar #22 - fidomuh
21. dec. 2012 08:30
#17

Et godt regex library kunne sagtens have funktioner til at konvertere strenge fra hvert af de forskellige formater til regex objekter og funktioner som kan kombinere regex objekter til nye regex objekter.


Der er flere af den slags libraries, som virker ganske fint, btw :)
Jeg fandt et til PHP i sin tid, men da jeg opdagede at "alle" bruger PerlRegex anyway, saa meh :D
Gravatar #23 - kasperd
21. dec. 2012 09:24
fidomuh (22) skrev:
Jeg fandt et til PHP i sin tid
Har du et link til det? For det vil jeg da gerne prøve at eksperimentere med på et tidspunkt.
Gravatar #24 - fjols
21. dec. 2012 10:40
milandt (10) skrev:
Kan godt li at løse problemer, også inden for områder som jeg ikke har så meget rerfaring med, men regex bliver jeg aldrig rigtig gode venner med.


Du kunne vel bare bruge .ToUpper() i C# til at tjekke om det er uppercase med ;)
Gravatar #25 - fidomuh
21. dec. 2012 10:56
#23

Nopes, det er *MEGET* laenge siden. Men det kunne tage POSIX regex praecis som det tog PERL regex. :)
Gravatar #26 - arne_v
21. dec. 2012 19:44
kasperd (17) skrev:
Et godt regex library kunne sagtens have funktioner til at konvertere strenge fra hvert af de forskellige formater til regex objekter og funktioner som kan kombinere regex objekter til nye regex objekter.


Med en rimelig feature kompabilitet, så burde det ikke være svært.
Gravatar #27 - arne_v
21. dec. 2012 19:46
fidomuh (21) skrev:
Skyldes ikke lidt at baade PHP, C# og Java valgte at implementere efter Perl-Regex og POSIX kun var standard i C, or so?


Java og .NET valgte Perl.

PHP valgte både Perl og POSIX, men kun Perl bruges.
Gå til top

Opret dig som bruger i dag

Det er gratis, og du binder dig ikke til noget.

Når du er oprettet som bruger, får du adgang til en lang række af sidens andre muligheder, såsom at udforme siden efter eget ønske og deltage i diskussionerne.

Opret Bruger Login