Czemu wyrażenie regularne w bibliotece MusicScoreViewer dopuszcza dodatkowo slash?

0

Weźmy ten plik z mojego projektu:

https://github.com/andrzejlisek/MusicScoreViewer/blob/master/pdf.js

Ja nie jestem autorem tego pliku, jest to nie najnowsza wersja biblioteki wyświetlającej PDF w JavaScript.

W tym pliku jest taki zapis /^[a-z]:[/\\]/i (linia 12996).

Jak to należy rozumieć? Z tego, co wiem, w Javascript, regex zaczyna się i kończy się znakiem /, a każdy znak tekstowy, który może pełnić funkcję specjalną (czyli między innymi /) musi być poprzedzony znakiem \. Tutaj jest od razu znak /, ale interpreter JavaScript jakimś cudem nie próbuje tego zinterpretować jako koniec wyrażenia. Taki sposób to tylko zamiennik zapisu new RegExp(somepattern).

Jak należy interpretować to wyrażenie? Ja rozumiem, że musi zaczynać się od jednej małej litery, potem musi nastapić dwukroper, a za dwukropkiem \, jednak za tymi trzema znakami może być cokolwiek. Mówiąc po ludzku, do tego wyrażenia pasuje każda pełna ścieżka dostępu z Windows przy literze dysku zapisanej małą literą. Rozumiem, że znak \ musi być zapisany podwójnie, bo pierwszy to nie jest znak wyrażenia, tylko wskazanie, że następny znak należy zinterpretować jako tekst. Ale po co jest tu znak /?

Znalazłem https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_regexp i przerobiłem przykładowy kod do testów:

<!DOCTYPE html>
<html>
<body>

<h2>JavaScript Regular Expressions</h2>

<p>Do a case-insensitive search for "w3schools" in a string:</p>

<p id="demo"></p>

<script>
let pattern1 = /^[a-z]:[/\\]/i;
let pattern2 = new RegExp("^[a-z]:[/\\\\]", "i");

alert(pattern1);
alert(pattern2);

if (pattern1 == pattern2)
{
  alert("to samo 1");
}
else
{
  alert("rozne 1");
}

if (pattern1 === pattern2)
{
  alert("to samo 2");
}
else
{
  alert("rozne 2");
}

</script>

</body>
</html>

Jak widać, pokazuje się dwa razy taki sam tekst, ale też pokazuje się "rozne 1" i "rozne 2". Jak powinien być napisany parametr w konstruktorze obiektu RegExp, żeby JaavaScript zinterpretował jako identyczny z omawianym zapisem z ukośnikami?

2

Poniższy kod już pokazuje komunikat o identyczności.

if (pattern1.toString() === pattern2.toString())
{
  alert("to samo 1");
}
0
overcq napisał(a):

Poniższy kod już pokazuje komunikat o identyczności.

if (pattern1.toString() === pattern2.toString())
{
  alert("to samo 1");
}

Prawda, ale to nie jest stwierdzenie identyczności obiektu jako takiego, tylko stwierdzenie identyczności efektu pewnego przekształcenia. To tak, jakbym napisał:

let Val1 = "0123";
let Val2 = "123";
if (parseInt(Val1) === parseInt(Val2))
{
  alert("to samo");
}
1

Zapis /^[a-z]:[/\\]/i to jest to samo co new Regex(`^[a-z]:[/\\\\]`, 'i');

Oba się dopasowują do:

  • ^ asercja początku podmiotu
  • [a-z] jeden znak z przedziału a-z
  • : - dwukropek dosłownie
  • [/\\] - slash lub backslash - / lub \.
andrzejlisek napisał(a):

Rozumiem, że znak \ musi być zapisany podwójnie, bo pierwszy to nie jest znak wyrażenia, tylko wskazanie, że następny znak należy zinterpretować jako tekst. Ale po co jest tu znak /?

Bo windows pozwala też na zapis ścieżki ze slashem. Ścieżka C:/Users/Riddle/ będzie poprawnie zinterpretowana, tak samo jak C:\Users\Riddle\.

0

Skoro część [/\\] znaczy "znak / lub \", a jednocześnie znak / rozpoczyna i kończy wyrażenie, to jak to jest, że znak / nie musi być poprzedzony znakiem \, który zasygnalizowałby, że nastąpi / jako znak, a nie jako koniec wyrażenia? Po czym interpreter JavaScript odróżnia koniec wyrażenia od znaku slash podanego wprost, skoro w jednym i drugim przypadku nie jest poprzedzony znakiem blackslash?

2
andrzejlisek napisał(a):

Skoro część [/\\] znaczy "znak / lub \", a jednocześnie znak / rozpoczyna i kończy wyrażenie, to jak to jest, że znak / nie musi być poprzedzony znakiem \, który zasygnalizowałby, że nastąpi / jako znak, a nie jako koniec wyrażenia? Po czym interpreter JavaScript odróżnia koniec wyrażenia od znaku slash podanego wprost, skoro w jednym i drugim przypadku nie jest poprzedzony znakiem blackslash?

Znak / nie zawsze kończy wyrażenie.

Jeśli znak jest:

  • Escape'owany, np \/
  • Znajduje się w character class: [/]
  • Znajduje się w cytacie: \Q/\E
  • Znajduje się w wyrażeniu controlnym \c/
  • Znajduje się w komentarzu (?#/)

to wtedy zachowuje się jak zwykły znak i nie kończy wyrażenia.

1 użytkowników online, w tym zalogowanych: 0, gości: 1